代码随想录day07| 454. 四数相加 II、383. 赎金信、15. 三数之和、18. 四数之和

文章概述了几道LeetCode题目,包括454.四数相加II、383.赎金信、15.三数之和和18.四数之和,主要讨论了如何通过巧妙的算法设计,如使用哈希映射、排序和去重,解决这些涉及数组操作的数学问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Leetcode454. 四数相加 II

注意:×

  1. 没想到好的解决办法,看了答案思路自己编写
  2. 方法巧妙的地方在于,将四个分组分成了两组,一组往里面填,一组验证,造了一个类似1.两数相加的案例
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        HashMap<Integer, Integer> hm = new HashMap<>();
        for (int n1 : nums1) {
            for (int n2 : nums2) {
                int sum = n1 + n2;
                hm.put(sum, hm.getOrDefault(sum, 0) + 1);
            }
        }
        int res = 0;
        for (int n3 : nums3) {
            for (int n4 : nums4) {
                int need = 0 - n3 - n4;
                if (hm.containsKey(need)) {
                    res = res+hm.get(need);
                }
            }
        }
        return res;
    }

Leetcode383. 赎金信

注意:√

  1. 注意一下题目要求,只要满足就可以,不需要顺序匹配
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;
    }

Leetcode15. 三数之和

注意:×

  1. 这种nSum解法是嵌套的
  2. 注意List的声明方式,应该是ArraList创建
  3. 问题1:调用twoSum的时候需要去除当前这个元素,怎么处理的?
  4. 回答:例如index=0的时候,传进去的
  5. 问题2:怎么直接创建一个匿名对象放进答案当中
  6. 回答:new ArrayList(Array.asList(a,b,c,d))
  7. 问题3:注意对threeSum部分进行去重
  8. 回答:在最外面的for循环部分添加while进行过滤
public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
//        List<List<Integer>> ans = new List<List<Integer>>;
        List<List<Integer>> ans = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            int need = 0 - nums[i];
            List<List<Integer>> ans_son = twoSum(nums, i + 1, need);
            for (List<Integer> list : ans_son) {
                list.add(nums[i]);
                ans.add(list);
            }
            // 加一个防止重复的判断
            while (i<nums.length-1 && nums[i]==nums[i+1]){i++;}
        }

        return ans;
    }

    private List<List<Integer>> twoSum(int[] nums, int start, int target) {
        int low = start;
        int high = nums.length - 1;
        List<List<Integer>> rt = new ArrayList<>();
        while (low < high) {
            int plus = nums[low] + nums[high];
            int left = nums[low];
            int right = nums[high];
            if (plus == target) {
                rt.add(new ArrayList<>(Arrays.asList(left, right)));
                while (low < high && nums[low] == left) {
                    low++;
                }
                while (low < high && nums[high] == right) {
                    high--;
                }
            } else if (plus < target) {
                while (low < high && nums[low] == left) {
                    low++;
                }
            } else if (plus > target) {
                while (low < high && nums[high] == right) {
                    high--;
                }
            }
        }
        return rt;
    }

Leetcode18. 四数之和

注意:×

  1. 通过案例很简单,在三数之和的基础上改改就好了,问题是注意数组元素和target取值变化了
  2. 只需要改一下4下面的函数的target和两数之和的target跟plus就好了
public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            int need = target - nums[i];
            List<List<Integer>> ans_son = threeSum(nums, i + 1, need);
            for (List<Integer> list : ans_son) {
                list.add(nums[i]);
                ans.add(list);
            }
            // 加一个防止重复的判断
            while (i<nums.length-1 && nums[i]==nums[i+1]){i++;}
        }

        return ans;
    }

    public List<List<Integer>> threeSum(int[] nums, int start, long target) {

//        List<List<Integer>> ans = new List<List<Integer>>;
        List<List<Integer>> ans = new ArrayList<>();
        for (int i = start; i < nums.length; i++) {
            long need = target - nums[i];
            List<List<Integer>> ans_son = twoSum(nums, i + 1, need);
            for (List<Integer> list : ans_son) {
                list.add(nums[i]);
                ans.add(list);
            }
            // 加一个防止重复的判断
            while (i<nums.length-1 && nums[i]==nums[i+1]){i++;}
        }

        return ans;
    }

    private List<List<Integer>> twoSum(int[] nums, int start, long target) {
        int low = start;
        int high = nums.length - 1;
        List<List<Integer>> ans = new ArrayList<>();
        while (low < high) {
            long plus = nums[low] + nums[high];
            int left = nums[low];
            int right = nums[high];
            if (plus == target) {
                ans.add(new ArrayList<>(Arrays.asList(left, right)));
                while (low < high && nums[low] == left) {
                    low++;
                }
                while (low < high && nums[high] == right) {
                    high--;
                }
            } else if (plus < target) {
                while (low < high && nums[low] == left) {
                    low++;
                }
            } else if (plus > target) {
                while (low < high && nums[high] == right) {
                    high--;
                }
            }
        }
        return ans;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值