我新建的个人博客,欢迎访问:hmilzy.github.io
454. 四数相加 II 题目链接: 四数相加 II
思路: 1.分为两组,HashMap 存一组,另一组和 HashMap 进行比对。 2.这样的话情况就可以分为三种: (1). HashMap 存一个数组,如 A。然后计算三个数组之和,如 BCD。时间复杂度为:O(n)+O(n^3),得到 O(n^3). (2). HashMap 存三个数组之和,如 ABC。然后计算一个数组,如 D。时间复杂度为:O(n^3)+O(n),得到 O(n^3). (3). HashMap存两个数组之和,如AB。然后计算两个数组之和,如 CD。时间复杂度为:O(n^2)+O(n^2),得到 O(n^2). 3.根据第二点我们可以得出要存两个数组算两个数组。 4.我们以存 AB 两数组之和为例。首先求出 A 和 B 任意两数之和 sumAB,以 sumAB 为 key,sumAB 出现的次数为 value,存入 hashmap 中。 然后计算 C 和 D 中任意两数之和的相反数 sumCD,在 hashmap 中查找是否存在 key 为 sumCD。 算法时间复杂度为 O(n2)。
思路参考:alela
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution { public int fourSumCount (int [] nums1, int [] nums2, int [] nums3, int [] nums4) { Map<Integer,Integer> map = new HashMap <>(); int temp; int result = 0 ; for (int i : nums1){ for (int j : nums2){ temp = i + j; if (map.containsKey(temp)){ map.put(temp,map.get(temp) + 1 ); }else { map.put(temp,1 ); } } } for (int i : nums3){ for (int j : nums4){ temp = i + j; if (map.containsKey(0 - temp)){ result += map.get(0 - temp); } } } return result; } }
383. 赎金信 题目链接: 赎金信
1.一些同学可能想,用数组干啥,都用map完事了,其实在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数,是费时的!数据量大的话就能体现出来差别了。 所以数组更加简单直接有效!只有26个字母嘛 2.遍历的顺序需要想清楚,先遍历更大更长的magzine,再遍历小的ransomNote,通过看数组的元素是否有小于零的来判断是否满足。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public boolean canConstruct (String ransomNote, String magazine) { int [] record = new int [26 ]; for (char c : magazine.toCharArray()){ record[c - 'a' ] += 1 ; } for (char c : ransomNote.toCharArray()){ record[c - 'a' ] -= 1 ; } for (int i : record){ if (i < 0 ){ return false ; } } return true ; } }
15. 三数之和 题目链接: 三数之和
先将数组排序,然后用头尾双指针。 本题的重点是要去重,参考下面的代码仔细分析。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Solution { public List<List<Integer>> threeSum (int [] nums) { List<List<Integer>> result = new ArrayList <>(); Arrays.sort(nums); for (int i = 0 ; i < nums.length; i++) { if (nums[i] > 0 ) { return result; } if (i > 0 && nums[i] == nums[i - 1 ]) { continue ; } int left = i + 1 ; int right = nums.length - 1 ; while (right > left) { int sum = nums[i] + nums[left] + nums[right]; if (sum > 0 ) { right--; } else if (sum < 0 ) { left++; } else { result.add(Arrays.asList(nums[i], nums[left], nums[right])); while (right > left && nums[right] == nums[right - 1 ]) right--; while (right > left && nums[left] == nums[left + 1 ]) left++; right--; left++; } } } return result; } }
18. 四数之和 题目链接: 四数之和
思路跟三数之和差不多。然后四个数会多一层for循环。双指针left right照常。 去重两重for 加 left right
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class Solution { public List<List<Integer>> fourSum (int [] nums, int target) { List<List<Integer>> result = new ArrayList <>(); Arrays.sort(nums); for (int i = 0 ; i < nums.length; i++) { if (nums[i] > 0 && nums[i] > target) { return result; } if (i > 0 && nums[i - 1 ] == nums[i]) { continue ; } for (int j = i + 1 ; j < nums.length; j++) { if (j > i + 1 && nums[j - 1 ] == nums[j]) { continue ; } int left = j + 1 ; int right = nums.length - 1 ; while (right > left) { long sum = (long ) nums[i] + nums[j] + nums[left] + nums[right]; if (sum > target) { right--; } else if (sum < target) { left++; } else { result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right])); while (right > left && nums[right] == nums[right - 1 ]) right--; while (right > left && nums[left] == nums[left + 1 ]) left++; left++; right--; } } } } return result; } }