代码随想录
HashMap
与Two Sum类似,用一个hashMap存储已经遍历过的a+b,把sum放进key, 把count放进value,判断c+d有没有hashMap中的元素,有的话提取map中的count,依次累加。与18.四数之和相比,不用去重
为什么用HashMap?
O(n2)
1. 计数逻辑错误
2. 基本语法错误
更新map中的次数时,用map.get(sum1)++,这样时错误的,因为 map.get(sum1) 返回的是一个 Integer 对象,而不是一个原始 int 类型。在 Java 中,Integer 对象是不可变的,这意味着不能直接修改它所包含的值。因此,不能直接对从哈希表获取的值进行自增操作。
正确的做法是:
如果 map 中已经包含了 sum1,需要先获取这个值,然后增加 1,最后再将新的值放回 map 中。
或者更简洁的写法是:map.getOrDefault
代码随想录
数组
时间复杂度:O(n+m)
空间复杂度:O(1)
1. 选用什么数据结构?有没有必要用map?
此题和anagram类似,最简单的做法也是定义一个size26的数组做哈希映射
没有必要用map。因为hashmap的底层是红黑树,实际时间和空间耗时都要更多一些(红黑树不了解,所以这里其实不太懂)
2. 如何把字符串转数组?
char[] = String.toCharArray
3. 判断逻辑。什么时候判定是false?
ransomNote对新数组元素做自增;
magazine对新数组元素做自减;
如果新数组元素有大于0的,说明ransomNote中存在magazine没有的字符,返回false
4. 在自己思考的时候尝试了map方法,但是在map更新计数这里卡住
记住map更新val的简单方法:
map.put(key, map.getOrDefault(key, 0)+1)
代码随想录
时间复杂度:O(n2)
空间复杂度:O(1)
1. 对原数组nums进行排序
2. 对a去重
if( i > 0 && nums[i] == nums[i - 1]){
i++
}
不能是nums[i] == nums[i+1]。为什么?假设数组是[-1, -1, 2],此时nums[0]=nums[1]=-1,那就会漏掉[-1, -1, 2]这种可能性
3. 循环条件
while(left < right)
不能是left==right,因为right==left时,b,c都是同一个指针,重复了
4. 对b,c去重
收获结果后继续遍历并要对b,c去重。且去重的逻辑必须放在收获结果的下面,因为至少要收获一个结果才能去重。否则会漏掉如[0,0,0,0]的结果[0,0,0]
while(left < right && nums[left] == nums[left+1]){
left++;
}
*这里要加上left
1. 基本函数使用
List<List<Integer>> arrayList = new ArrayList<>();
arrayList.add(Arrays.asList(nums[i], nums[left], nums[right]))
2. 去重逻辑
2.1. 对a去重:在每次循环的开始检查并跳过重复元素
❌错误(1): 把a的去重代码放在了for循环的末尾。为什么错了?
❌错误(2): 对i去重的移动写的是i++,而不是continue。为什么要写continue,而不是i++,两者的区别是什么?
2.2 对b,c去重:找到有效的三元组之后去重
❌错误(1): 对b,c的去重放在了else代码块之外。这样left和right的移动会跳过一些数
❌错误(2): 对b,c的去重要用while循环来校验,而不是if,因为left和right在移动过程中可能连着好几个数字都一样
❌错误(3): 跳出去重的while循环后,没有进行left++和right--