哈希表——快速判断一个元素是否出现集合里
242.有效的字母异位词
tips:
1、Java中 chatAT(index) 方法,表示返回字符串中索引为index的字符。
2、Java中两个字符相加或相减,表示的是它们的ASCII码值相加或者相减,返回值是int类型
349. 两个数组的交集
思路很简单,输出结果无序、不重复,java中立马想到HashSet。问题在于对HashSet的一些调用方法不熟练.
set.add(object); //set集合不允许重复值,添加重复值,会被覆盖,set结构不变。
202. 快乐数
问题有二:1、无限循环怎么破解。2、n的大小不确定,怎么取余,确定边界。
1、无限循环意味着平方和会出现重复,一出现重复就说明是无限循环,返回false。
2、设循环,n取余一次,整除一次,n为0时结束循环。(n小于10时整除10 为0
1.两数之和
做题之前想想以下四个点
本题其实有四个重点:
- 为什么会想到用哈希表
- 哈希表为什么用map
- 本题map是用来存什么的:存元素、存下标)(怎么存
- map中的key和value用来存什么的
tips:map中存入的键值对是反过来的。key——数组中的值,value——数组下标。
map.get(key):因为map只能通过key取value。
454.四数相加II
还是对Java中包装的HashMap方法不熟悉。
map.getOrDefault(Object key, V defaultValue)
//当Map集合中有这个key时,返回该key值对应的value,如果没有就使用默认值defaultValue
map.put(Object key,Object value); //当key值重复添加时,会被覆盖。
如果不想被覆盖,需要自定义重写put方法。
383. 赎金信
思路等用于有效的字母异位词。不同点在于最后判断record数组的全部元素是否大于等于0。
for(char a : magazine.toCharArray()) //获取单个字符的方法
15. 三数之和
需要解决的三个点:
1、双指针法如何相加?指针如何移动?
2、如何去重?从而确保,多个元组不重复,元组内的元素可以重复?
3、剪枝处理
第一个问题:指针如何移动 a = nums[i],b = nums[left],c = nums[right]。使得a+b+c=0。
- i如何移动:循环while(left<right),当left=right时,循环结束,i右移。
- left如何移动:数组是从左到右,由大到小排序的。若a+b+c<0,则left右移。
- right如何移动:同上,若a+b+c>0,则right左移。
第二个问题:如何去重,说到底是对a,b,c的去重。
1、对a的去重:当nums[i] == nums[i-1]时,重复。
当前指针所指的值与前一个值相等,说明这个值与其他值所有的排列组合,上一个值已经全部走了一遍。如有相加为0的,说明重复。
tips:判断nums[i] == nums[i+1]是没用的,因为会把{-1,-1,2}这种元组内有重复元素的跳过。(判断是否重复当然是要和已经走过一遍的值判断。
2、left与right的去重:
第三个问题:剪枝处理,提前将不符合的条件去掉,提高效率。
nums[i]>0;
18. 四数之和
与三数之和类似。区别在于a,b,c,d。嵌套循环先确定a,b;left与right指针寻找c,d。
重点说一下剪枝处理。
一级剪枝:nums[k] > target && nums[k] > = 0
二级剪枝:nums[k] + nums[i] > target && nums[k] + nums[i] > = 0;
遇到的问题:
剪枝和二级剪枝时,与上一题不同,不能使用return result直接返回结果;而是使用break跳过,继续判断下面的值。
否则下面的测试用例通不过
(为什么啊?怎么也不走这两个分支啊 a =-2,b=1,a=-1,b=0。a=-2,b=2;
晓得了,a=-2,b=3时会走这个分支
直接取消二级剪枝,测试用例全通过。