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

63 阅读1分钟

今天是哈希表和双指针的练习

454. 四数相加 II

解法是分组和哈希表

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

383. 赎金信

这是道简单题,哈希表直接解决

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        HashMap<Character, Integer> map = new HashMap<>();
        for(char c : magazine.toCharArray()) {
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        for(char c : ransomNote.toCharArray()) {
            map.put(c, map.getOrDefault(c, 0) - 1);
            if(map.get(c) < 0) return false;
        }
        return true;
    }
}

15. 三数之和

双指针解法

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

18. 四数之和

类似上一道题,就是再加了一层迭代,不过可以做优化

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        int len = nums.length;
        for(int a = 0; a < len - 3; a++) {
            long x = nums[a];
            //判断重复
            if(a > 0 && nums[a - 1] == nums[a])continue;
            //优化1
            if(x + nums[a + 1] + nums[a + 2] + nums[a + 3] > target)break;
            //优化2
            if(x + nums[len -3] + nums[len - 2] + nums[len - 1] < target)continue;
            for(int b = a + 1; b < len - 2; b++) {
                long y = nums[b];
                //判断重复
                if(b > a + 1 && nums[b - 1] == nums[b])continue;
                if(x + y + nums[b + 1] + nums[b + 2] > target)break;
                if(x + y + nums[len - 2] + nums[len - 1] < target)continue;
                int l = b + 1, r = len - 1;
                while(l < r) {
                    long sum = x + y + nums[l] + nums[r];
                    if(sum == target) {
                        res.add(Arrays.asList((int)x, (int)y, nums[l], nums[r]));
                        l++;
                        while(l < r && nums[l - 1] == nums[l])l++;
                        r--;
                        while(l < r && nums[r + 1] == nums[r])r--; 
                    } else if(sum < target){
                        l++;
                    } else {
                        r--;
                    }
                }
            }
        }
        return res;
    }
}