从这周开始继续打周赛,尝试以赛促练,以后也想专门记录一下每周周赛一些我不会的题目,以及别人好的思路。

这次又只AC了前两题,基本上就是模拟,没有什么好说的。第三题本来一眼看以为是区间修改,线段树,结果一想自己线段树也不会啊,故尝试HashMap<String,HashMap<String,Integer>>模拟,结果TLE,过了72/77,一检查确2x104xN确实超了,时间也没了;第四题一眼看联想到了以前做的字典树,结果和优质数对的数量也没啥关系啊,先排序然后尝试在树上再二分这个做法也没法去实现。总而言之,还是做的题目类型太少,容器使用也不熟练。

大佬的手速场,我的反思场,哎,算法这条路还是道阻且长啊。

T3.6126.设计食物评分系统

设计一个支持下述操作的食物评分系统:

修改系统中列出的某种食物的评分。
返回系统中某一类烹饪方式下评分最高的食物。 实现 FoodRatings 类:

FoodRatings(String[] foods, String[] cuisines, int[] ratings)初始化系统。食物由 foods、cuisines 和 ratings 描述,长度均为n。
foods[i] 是第 i 种食物的名字。
cuisines[i] 是第 i 种食物的烹饪方式。
ratings[i] 是第 i 种食物的最初评分。
void changeRating(String food, int newRating) 修改名字为 food 的食物的评分。
String highestRated(String cuisine) 返回指定烹饪方式 cuisine 下评分最高的食物的名字。如果存在并列,返回字典序较小的名字。注意,字符串 x 的字典序比字符串 y 更小的前提是:x 在字典中出现的位置在 y 之前,也就是说,要么 x 是 y 的前缀,或者在满足 x[i] != y[i] 的第一个位置 i 处,x[i] 在字母表中出现的位置在 y[i] 之前。

示例:

输入 [“FoodRatings”, “highestRated”, “highestRated”, “changeRating”,
“highestRated”, “changeRating”, “highestRated”] [[[“kimchi”, “miso”,
“sushi”, “moussaka”, “ramen”, “bulgogi”], [“korean”, “japanese”,
“japanese”, “greek”, “japanese”, “korean”], [9, 12, 8, 15, 14, 7]],
[“korean”], [“japanese”], [“sushi”, 16], [“japanese”], [“ramen”, 16],
[“japanese”]] 输出 [null, “kimchi”, “ramen”, null, “sushi”, null,
“ramen”]

解释 FoodRatings foodRatings = new FoodRatings([“kimchi”, “miso”,
“sushi”, “moussaka”, “ramen”, “bulgogi”], [“korean”, “japanese”,
“japanese”, “greek”, “japanese”, “korean”], [9, 12, 8, 15, 14, 7]);
foodRatings.highestRated(“korean”); // 返回 “kimchi”
// “kimchi” 是分数最高的韩式料理,评分为 9 。 foodRatings.highestRated(“japanese”); // 返回 “ramen”
// “ramen” 是分数最高的日式料理,评分为 14 。 foodRatings.changeRating(“sushi”, 16); // “sushi” 现在评分变更为 16 。
foodRatings.highestRated(“japanese”); // 返回 “sushi”
// “sushi” 是分数最高的日式料理,评分为 16 。 foodRatings.changeRating(“ramen”, 16); // “ramen” 现在评分变更为 16 。
foodRatings.highestRated(“japanese”); // 返回 “ramen”
// “sushi” 和 “ramen” 的评分都是 16 。
// 但是,“ramen” 的字典序比 “sushi” 更小。

提示:

1 <= n <= 2 * 104
n == foods.length == cuisines.length ==ratings.length
1 <= foods[i].length, cuisines[i].length <= 10
foods[i]、cuisines[i] 由小写英文字母组成
1 <= ratings[i] <= 108
foods 中的所有字符串互不相同
在对 changeRating 的所有调用中,food 是系统中食物的名字。
在对 highestRated的所有调用中,cuisine 是系统中 至少一种 食物的烹饪方式。
最多调用 changeRating 和 highestRated 总计 2 * 104

之前我的模拟中,String highestRated(String cuisine)是遍历所有菜名,找到烹饪方式和cuisine相同的菜进行比较,2x104xN存在超时。这里我们进行优化,由于需要返回一种烹饪方式中rating最高的菜的名字,可以采用类似TreeMap<Food>数据结构存储同一类烹饪方式的菜,并定义其排序规则,虽然建立红黑树的总时间为O(NlogN),但是排序后查询只需要2x104 xO(1),最后同一类的菜用HashMap<String,TreeMap<Food>>存储。

class FoodRatings {public class Food{String foodname;String cuisine;int rating;public Food(String _foodname, String _cuisine, int _rating){this.foodname=_foodname;this.cuisine=_cuisine;this.rating=_rating;}}//烹饪方式和food的映射,用于String highestRated(String cuisine)HashMap<String,TreeSet<Food>> map;//菜名和food的映射,用于void changeRating(String food, int newRating)HashMap<String,Food> objMap;public FoodRatings(String[] foods, String[] cuisines, int[] ratings) {int len=foods.length;map=new HashMap<>();objMap=new HashMap<>();for(int i=0;i<len;i++){Food food=new Food(foods[i],cuisines[i],ratings[i]);TreeSet<Food> cuiSet=map.getOrDefault(cuisines[i],new TreeSet<>((o1,o2)->{if(o1.rating==o2.rating){//字典序升序,o1->o2小的减去大的return o1.foodname.compareTo(o2.foodname);}else{return o2.rating-o1.rating;}}));cuiSet.add(food);map.put(cuisines[i],cuiSet);objMap.put(foods[i],food);}}public void changeRating(String foodname, int newRating) {Food foodObj=objMap.get(foodname);String _cuisine=foodObj.cuisine;Food newFood=new Food(foodname,_cuisine,newRating);TreeSet<Food> cuiSet=map.get(_cuisine);//原先的TreeSet中删除旧节点cuiSet.remove(foodObj);cuiSet.add(newFood);map.put(_cuisine,cuiSet);objMap.put(foodname,newFood);}public String highestRated(String cuisine) {TreeSet<Food> cuiSet=map.get(cuisine);Food food=cuiSet.first();return food.foodname;}
}/*** Your FoodRatings object will be instantiated and called as such:* FoodRatings obj = new FoodRatings(foods, cuisines, ratings);* obj.changeRating(food,newRating);* String param_2 = obj.highestRated(cuisine);*/

其中用lambda表达式建立TreeSet的代码值得学习,其中排序规则多行定义,需要(o1,o2)->{ }有括号,且其中排序语句末尾不需要分号;

TreeSet<Food> cuiSet=map.getOrDefault(cuisines[i],new TreeSet<>((o1,o2)->{if(o1.rating==o2.rating){//字典序升序,o1->o2可以理解为一直是排序后小的减去大的那个表达式return o1.foodname.compareTo(o2.foodname);}else{return o2.rating-o1.rating;}}));

用lambda表达式建立PriorityQueue的代码同样值得学习,其中规则只有一行定义,(o1,o2)->不需要括号,且其中排序语句末尾不需要分号;

PriorityQueue<Integer> que=new PriorityQueue<>((o1,o2)->Math.abs(o1)-Math.abs(o2));

T4. 6127.优质数对的数目

给你一个下标从 0 开始的正整数数组 nums 和一个正整数 k 。

如果满足下述条件,则数对 (num1, num2) 是 优质数对 :

num1 和 num2 都 在数组 nums 中存在。 num1 OR num2 和 num1 AND num2 的二进制表示中值为 1
的位数之和大于等于 k ,其中 OR 是按位 或 操作,而 AND 是按位 与 操作。 返回 不同 优质数对的数目。

如果 a != c 或者 b != d ,则认为 (a, b) 和 (c, d) 是不同的两个数对。例如,(1, 2) 和 (2, 1)
不同。

注意:如果 num1 在数组中至少出现 一次 ,则满足 num1 == num2 的数对 (num1, num2) 也可以是优质数对。

示例 1:

输入:nums = [1,2,3,1], k = 3 输出:5 解释:有如下几个优质数对:

  • (3, 3):(3 AND 3) 和 (3 OR 3) 的二进制表示都等于 (11) 。值为 1 的位数和等于 2 + 2 = 4 ,大于等于 k = 3 。
  • (2, 3) 和 (3, 2): (2 AND 3) 的二进制表示等于 (10) ,(2 OR 3) 的二进制表示等于 (11) 。值为 1 的位数和等于 1 + 2 = 3 。
  • (1, 3) 和 (3, 1): (1 AND 3) 的二进制表示等于 (01) ,(1 OR 3) 的二进制表示等于 (11) 。值为 1 的位数和等于 1 + 2 = 3 。 所以优质数对的数目是 5 。

示例 2:

输入:nums = [5,1,1], k = 10 输出:0 解释:该数组中不存在优质数对。

提示:

1 <= nums.length <= 105
1 <= nums[i] <= 109
1 <= k <= 60

这题参考题解灵神的题解。意识到 A or B + A and B是A、B两数的二进制中1的和是关键,因此可以先分别统计nums中所有数字二进制1的个数,在统计之前,观察到数对可以交换顺序,因此考虑去重。在遍历nums的过程中,用HashMap<Integer,Integer> cnt记录,key为nums[i]二进制1的个数,不超过30个,Value记录不同nums[i]的个数。两次循环遍历cnt,根据位数之和>=k,最后累加产生优质数对的数目。

//time:O(N)
class Solution {public long countExcellentPairs(int[] nums, int k) {long ans=0L;HashSet<Integer> vis=new HashSet<>();HashMap<Integer,Integer> cnt=new HashMap<>();for(int i:nums){//去重的过程中统计二进制中1的位数if(!vis.contains(i)){vis.add(i);int bitnum=Integer.bitCount(i);/**getOrDefault位置不能随意互换 */cnt.put(bitnum,cnt.getOrDefault(bitnum,0)+1);}}for(Map.Entry<Integer,Integer> i:cnt.entrySet()){for(Map.Entry<Integer,Integer> j:cnt.entrySet()){if(i.getKey()+j.getKey()>=k){ans+=(long)i.getValue()*j.getValue();}}}return ans;}
}

以赛促练-力扣第303场周赛反思相关推荐

  1. 以赛促练-力扣第85场双周赛以及第307场周赛

    文章目录 第85场双周赛 T3.字母移位II T4.删除操作后的最大子段和 第307场周赛 T2.最大回文数字 T3.感染二叉树需要的总时间 T4.找出数组的第K大和 第85场双周赛 T1直接暴力枚举 ...

  2. 力扣第303场周赛补题

    力扣 第三题:设计食物评分系统 示例 输入 ["FoodRatings", "highestRated", "highestRated", ...

  3. 20220307:力扣第283场周赛(上)

    力扣第283场周赛(上) 题目 思路与算法 代码实现 写在最后 题目 Excel 表中某个范围内的单元格 向数组中追加 K 个整数 思路与算法 第一题直接模拟即可,注意作为char的数字也是可以直接自 ...

  4. 20220228:力扣第282场周赛(下)

    力扣第282场周赛(下) 题目 思路与算法 代码实现 写在最后 题目 完成旅途的最少时间 完成比赛的最少时间 思路与算法 完成旅途的最少时间: 二分模板题,注意初始化左右边界的话,速度会提升很多. 完 ...

  5. 20220227:力扣第282场周赛(上)

    力扣第282场周赛(上) 题目 思路与算法 代码实现 写在最后 题目 统计包含给定前缀的字符串 使两字符串互为字母异位词的最少步骤数 思路与算法 第二题直接并集减去交集,简单的集合运算,当然也可以换C ...

  6. 20220213:力扣第280场周赛(上)

    力扣第280场周赛(上) 题目 思路与算法 代码实现 写在最后 题目 得到 0 的操作数 使数组变成交替数组的最少操作数 思路与算法 简单模拟即可,所谓辗转相除法 哈希处理,然后找到最大和次大值即可. ...

  7. 20220212:力扣第277场周赛(下)

    力扣第277场周赛(上) 题目 思路与算法 代码实现 写在最后 题目 找出数组中的所有孤独数字 基于陈述统计最多好人数 思路与算法 找出数组中的所有孤独数字 按照题意模拟即可,使用map来统计即可. ...

  8. 20220123:力扣第277场周赛(上)

    力扣第277场周赛(上) 题目 思路与算法 代码实现 写在最后 题目 元素计数 按符号重排数组 思路与算法 元素计数 按符号重排数组 无需多言,直接按照题目实现就行了,过于敷衍了这两个题,简单记录一下 ...

  9. 20220104:力扣第274场周赛(下)

    力扣第274场周赛(下) 题目 思路与算法 代码实现 写在最后 题目 摧毁小行星 参加会议的最多员工数 思路与算法 第3题简单模拟即可,注意使用long long格式进行保存累加结果.有二元组的简单比 ...

最新文章

  1. springboot 整合redis 实现KeySpaceNotification 键空间通知
  2. 为什么大型科技公司更会发生人员流失 标准 ceo 软件 技术 图 阅读2479 原文:Why Good People Leave Large Tech Companies 作者:steve
  3. mongodb中分页显示数据集的学习
  4. spring核心:bean工厂的装配 1
  5. Alpha版(内部测试版)发布
  6. 用计算机创造的音乐,【电影音乐论文】计算机音乐技术在电影音乐中的运用(共1977字)...
  7. 从跑步小白到马拉松、再到百公里越野跑的晋级之路
  8. 三种健身妙法-每天五分钟简便易行有宏效
  9. .NetCore异常:Could not load file or assembly ‘Microsoft.AI.Web‘ or one of its dependencies. The system
  10. word加上尾注之后参考文献下面的横线去除
  11. http client的英文文档 牛逼
  12. 二代测序的原理和简介
  13. EXTRA_CFLAGS += -D 与CONFIG_ =y
  14. MFC编程实例二:进度条的使用
  15. 你真的会使用github吗?
  16. 互联网巨头吃小鱼:终端背后的十亿消费者
  17. 小伙用C++代码实现P2P穿透文件传输,网友集体打call!
  18. 破解Linux/GRUB/BIOS密码
  19. MySQL slave状态之Seconds_Behind_Master
  20. 有什么网上赚钱的项目?怎么操作?

热门文章

  1. uwb高精度定位技术应用分析,高精度定位服务为行业应用带来哪些价值?
  2. 【最强最全车牌识别算法】支持13种中文车牌识别的云端API部署(可直接获取源码使用)
  3. 车牌--常用车牌定位算法浅析
  4. Python文件中头部的 #!(shebang) 基本解释
  5. [理论]领域驱动设计 DDD 是啥,cqrs是啥
  6. 利用FIleZilla Server在局域网搭建在线点播电脑本地文件电影FTP
  7. 【人工智能】AGI 通用人工智能基础概念、实现原理、挑战和发展前景
  8. 利用U盘重装系统的方法
  9. python怎么获取token值_python 产生token及token验证
  10. dpkg 删除软件_apt-get remove 和dpkg --remove 无法删除软件