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

454.四数相加II

题目链接:力扣

解题思路:使用哈希表的map

① 遍历num1和num2数组,key放a和b两数之和,value 放a和b两数之和出现的次数

② 再遍历num3和num4数组,如果0-(c+d)在map中出现过,就用count把key对应的value也就是出现次数统计出来

代码如下:

public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int res = 0;
        Map map = new HashMap();
        //统计两个数组中的元素之和,同时统计出现的次数,放入map
        for (int i : nums1) {
            for (int j : nums2) {
                int sum = i + j;
                map.put(sum, map.getOrDefault(sum, 0) + 1);
            }
        }
        //统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数
        for (int i : nums3) {
            for (int j : nums4) {
                res += map.getOrDefault(0 - i - j, 0);
            }
        }
        return res;
    }

383. 赎金信

题目链接:力扣

解题思路:我自己做的时候使用的是哈希表的map,但看解答用的数组更方便一点

代码如下:

public boolean dcanConstruct(String ransomNote, String magazine) {
        Map map = new HashMap<>();
        for (int i = 0; i < ransomNote.length(); i++) {
            map.put(ransomNote.charAt(i) - 'a', map.getOrDefault(ransomNote.charAt(i) - 'a',0) + 1);
        }

        for (int i = 0; i < magazine.length(); i++) {
            int num = magazine.charAt(i) - 'a';
            map.put(num, map.getOrDefault(num, 0 ) - 1);
        }

        Iterator> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = iterator.next();
            if(entry.getValue() > 0) {
                return false;
            }
        }
        return true;

    }
public boolean canConstruct(String ransomNote, String magazine) {
        // shortcut
        if (ransomNote.length() > magazine.length()) {
            return false;
        }
        // 定义一个哈希映射数组
        int[] record = new int[26];

        // 遍历
        for(char c : magazine.toCharArray()){
            record[c - 'a'] += 1;
        }

        for(char c : ransomNote.toCharArray()){
            record[c - 'a'] -= 1;
        }
        
        // 如果数组中存在负数,说明ransomNote字符串总存在magazine中没有的字符
        for(int i : record){
            if(i < 0){
                return false;
            }
        }

        return true;
    }

15. 三数之和

题目链接:力扣

解题思路:先对列表进行排序,再遍历,设置左右指针,重点在如何去重。这个思想还要再学习一下。

代码如下:

public List> threeSum(int[] nums) {
        List> results = new ArrayList<>();
        Arrays.sort(nums);

        for (int i = 0; i < nums.length; i++) {
            if(nums[i] > 0) {
                return results;
            }

            if(i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

            int left = i + 1;
            int right = nums.length - 1;
            while(left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if(sum < 0) {
                    left++;
                } else if(sum > 0) {
                    right--;
                } else {
                    results.add(Arrays.asList(nums[i], nums[left], nums[right]))
                    while (right > left && nums[left] == nums[left + 1]) left++;
                    while (right > left && nums[right] == nums[right - 1]) right--;

                    right--;
                    left++;
                }

            }

        }
        return results;
    }

18. 四数之和

题目链接:力扣

解题思路:和三数之和差不多,多了一层循环。自己思考的时候设置了三个指针,然后绕昏了解不出来,看完卡哥的视频再写就清楚多了,但要注意最后sum为long型

代码如下:

public List> fourSum(int[] nums, int target) {
        List> res = new ArrayList<>();
        Arrays.sort(nums);

        for(int k = 0; k < nums.length; k++) {
            if(nums[k] > target && target > 0) {
                return res;
            }
            if(k > 0 && nums[k] == nums[k - 1]) {
                continue;
            }
            for (int i = k + 1; i < nums.length; i++) {

                if(i > k + 1  && nums[i] == nums[i - 1]) {
                    continue;
                }

                int left = i + 1;
                int right = nums.length - 1;

                while(left < right) {
                    long sum = (long)nums[k] + nums[i] + nums[left] + nums[right];
                    if(sum < target) {
                        left++;
                    } else if (sum > target) {
                        right--;
                    } else {
                        res.add(Arrays.asList(nums[k], nums[i], nums[left], nums[right]));
                        while(left < right && nums[left] == nums[left + 1]) left++;
                        while (left < right && nums[right] == nums[right - 1]) right--;
                        left++;
                        right--;
                    }
                }
            }
        }
        return res;
    }

今日心得

双指针的思想处处存在,遇到就要好好学习总结。对哈希表的理解也更深刻了。

学习使我快乐

你可能感兴趣的:(算法)