Leetcode 454 力扣
解法:哈希判断四数之和的目标值减去两数之和是否包含,两数之和的变形题
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) { Map<Integer,Integer> map = new HashMap<>(); int res =0; for (int i = 0; i < nums1.length; i++) { for (int j = 0; j < nums2.length; j++) { int temp = nums1[i] +nums2[j]; // 两数之和先存入哈希 if (map.containsKey(temp)){ map.put(temp,map.get(temp) +1); }else { map.put(temp,1); } } } for (int i = 0; i < nums3.length; i++) { for (int j = 0; j < nums4.length; j++) { int temp = nums3[i] +nums4[j]; if (map.containsKey(0 - temp)){ // 目标值减两数之和是否在哈希中 res += map.get(0-temp); // 存在累计计数 } } } return res; }
Leetcode 383 力扣
解法:有效字母异位词变形题。在于哈希数组统计消除字符后count细节判断
public static boolean canConstruct(String ransomNote, String magazine) { int[] records = new int[26]; for (int i = 0; i < ransomNote.length(); i++) { // count>0 说明ransomNote字符比magazine多 records[ransomNote.charAt(i) - 'a']++; } for (int i = 0; i < magazine.length(); i++) { records[magazine.charAt(i) - 'a']--; } for (int count : records) { if (count > 0) { // 这里是要思考的点,count为0完全匹配,count>0和count<0看谁是++就是谁字符多 return false; } } return true; }
Leetcode 15 力扣
说实话这题之前做过两次,再次做还是自己AC不了,梦想走了。去重细节还需要再吃透。
下次做还是不会做,还是细节地方需要多练多巩固。
解法:固定一个数,然后使用双指针+剪枝去重
public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> result = new ArrayList<>(); Arrays.sort(nums); // 先排序 for (int i = 0; i < nums.length; i++) { // 固定i if (nums[i] > 0) { // 大于0直接返回 return result; } if (i > 0 && nums[i] == nums[i - 1]) { // nums[i] == nums[i + 1]会排除掉结果集[-1,-1,2] continue; } int left = i + 1; int right = nums.length - 1; while (right > left) { // 循环条件=号带不带,当left=right,只有两个元素 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[left] == nums[left+1]){ // 后对left去重 left++; } while (right>left && nums[right] == nums[right-1]){ // 后对right去重 right--; } // left 和 right去重后,left和right继续移动收集下一个结果集 right--; left++; } } } return result; }
Leetcode 18 力扣
解法:三数之和变形题,target为可输入,考虑为负数情况,固定两个数+双指针+剪枝去重
public List<List<Integer>> fourSum(int[] nums, int target) { // target为输入值,存在负数情况 Arrays.sort(nums); // 先排序 List<List<Integer>> result =new ArrayList<>(); for (int i = 0; i < nums.length; i++) { // 固定i if (nums[i] > target && nums[i] >0 && target>0){ // 剪枝操作,负数情况得保证排序后nums[i] >0才行 return result; } if (i>0 && nums[i] == nums[i-1]){ // a去重 continue; } for (int j = i+1; j < nums.length; j++) { // 固定j if (j >i+1 && nums[j] == nums[j-1]){ // b去重 continue; } int left = j+1; int right = nums.length-1; while (right >left){ // 双指针移动 long sum = 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[left] == nums[left+1]){ // left去重 left++; } while (right>left && nums[right] == nums[right-1]){ // right去重 right--; } // left 和 right去重后,left和right继续移动收集下一个结果集 left++; right--; } } } } return result; }