代码随想录训练营二刷第七天 | 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

代码随想录训练营二刷第七天 | 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

一、454.四数相加II

题目链接:https://leetcode.cn/problems/4sum-ii/
思路:求索引的组合,转化为两组,a+b = -(c+d),map中键为a+b,值为出现的次数。然后去匹配c+d即可。

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int sum = 0;
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i : nums1) {
            for (int j : nums2) {
                int temp = i + j;
                map.put(temp, map.getOrDefault(temp, 0) + 1);
            }
        }
        for (int i : nums3) {
            for (int j : nums4) {
                int temp = i + j;
                if (map.containsKey(-temp)) {
                    sum += map.getOrDefault(-temp, 0);
                }
            }
        }
        return sum;
    }
}

二、383. 赎金信

题目链接:https://leetcode.cn/problems/ransom-note/
思路:字母经典数组操作。数组里如果存放r字符串要变量3次(如果使用一个变量计数就可以只遍历2次),如果存放m字符串只需要遍历2次。

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[] nums = new int[26];
        for (int i = 0; i < ransomNote.length(); i++) {
            nums[ransomNote.charAt(i)-'a']++;
        }
        for (int i = 0; i < magazine.length(); i++) {
            if (nums[magazine.charAt(i)-'a'] > 0) {
                nums[magazine.charAt(i)-'a']--;
            }
        }
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != 0) {
                return false;
            }
        }
        return true;
    }
}

// =======================
public boolean canConstruct(String ransomNote, String magazine) {
        int[] nums = new int[26];
        int sum = 0;
        for (int i = 0; i < ransomNote.length(); i++) {
            nums[ransomNote.charAt(i)-'a']++;
            sum++;
        }
        for (int i = 0; i < magazine.length(); i++) {
            int k = magazine.charAt(i) - 'a';
            if (nums[k] > 0) {
                nums[k]--;
                sum--;
            }
        }
        
        return sum == 0;
    }

三、15. 三数之和

题目链接:https://leetcode.cn/problems/3sum/
思路:三数之和收集数组中元素,可以排序后,内层双指针遍历,去重,从a\b\c收集时考虑,和自己上一次收集的值一致时即跳过。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> list = new ArrayList<>();
        for (int i = 0; i < nums.length - 2; i++) {
            if (i > 0 && nums[i] == nums[i-1]) continue;
            int j = i+1, k = nums.length - 1;
            while (j < k) {
                int temp = nums[i] + nums[j] + nums[k];
                if (temp == 0) {
                    list.add(Arrays.asList(nums[i], nums[j], nums[k]));
                    while (j < k && nums[j] == nums[j+1]) j++;
                    while (j < k && nums[k] == nums[k-1]) k--;
                    j++;
                    k--;
                }else if (temp > 0) {
                    k--;
                } else {
                    j++;
                }
            }
        }
        
        return list;
    }
}

四、18. 四数之和

题目链接:https://leetcode.cn/problems/4sum/
思路:注意剪枝,去重。

public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> list = new ArrayList<>();
        for (int i = 0; i < nums.length - 3; i++) {
            if (nums[i] > 0 && nums[i] > target) return list;
            if (i > 0 && nums[i] == nums[i-1]) continue;
            for (int j = i+1; j < nums.length -2; j++) {
                if (nums[j] + nums[i] > target && nums[i] >= 0) {
                    break;
                }
                if (j > i+1 && nums[j] == nums[j-1]) continue;
                int k = j + 1, h = nums.length - 1;
                while (k < h) {
                    long temp = (long) nums[i] + nums[j] + nums[k] + nums[h];
                    if (temp < target) {
                        k++;
                    }else if (temp > target) {
                        h--;
                    } else {
                        list.add(Arrays.asList(nums[i], nums[j], nums[k], nums[h]));
                        while (k < h && nums[k] == nums[k+1]) k++;
                        while (k < h && nums[h] == nums[h-1]) h--;
                        k++;
                        h--;
                    }
                }
            }
        }
        return list;
    }

你可能感兴趣的:(力扣算法题,算法,数据结构)