zoukankan      html  css  js  c++  java
  • 【LeetCode】18. 四数之和

    链接:

    https://leetcode-cn.com/problems/4sum

    描述:

    给定一个包含 n 个整数的数组 nums 和一个目标值 target,
    判断 nums 中是否存在四个元素 a,b,c 和 d ,
    使得 a + b + c + d 的值与 target 相等?
    找出所有满足条件且不重复的四元组。

    注意:
    答案中不可以包含重复的四元组。

    示例:
    给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
    满足要求的四元组集合为:
    [
    [-1, 0, 0, 1],
    [-2, -1, 1, 2],
    [-2, 0, 0, 2]
    ]

    List<List<Integer>> fourSum(int[] nums, int target) {}

    思路1:两层循环 + 双指针

    在“三数之和”上加上一层循环即可。

    详见 三数之和
    https://www.cnblogs.com/crazyBlogs/p/13154267.html

    class Solution {
        public List<List<Integer>> fourSum(int[] nums, int target) {
            List<List<Integer>> result = new ArrayList();
            Arrays.sort(nums);
            for(int i = 0; i < nums.length; i++){
                if(i > 0 && nums[i] == nums[i - 1]){ continue;}
                for(int j = i + 1; j < nums.length; j++){
                    if(j > i + 1 && nums[j] == nums[j - 1]){ continue;}
                    int left = j + 1, right = nums.length - 1;
                    while(left < right){
                        int sum = nums[i] + nums[j] + nums[left] + nums[right];
                        if(sum == target){
                            result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                            left++;
                            right--;
                            while(left < right && nums[left] == nums[left - 1]){ left++;}
                            while(left < right && nums[right] == nums[right + 1]){ right--;}
                        }else if(sum < target){
                            left++;
                            while(left < right && nums[left] == nums[left - 1]){ left++;}
                        }else{
                            right--;
                            while(left < right && nums[right] == nums[right + 1]){ right--;}
                        }  
                    }
                }          
            }
            return result;
        }
    }
    

    思路2:回溯

    回溯法重要的步骤是剪枝

    将nums按照升序进行排序,四元组中没确定的数字个数设为n
    剪枝的情况:

    1. 剩余可选的数字数量小于n,返回
    2. 递归中当前数字与前一个相同,进行下一次循环
    3. 当前数字 + 已确定的数字的和 + (n-1)*剩余数组中最小的数字 > target,返回
    4. 当前数字 + 已确定的数字的和 + (n-1)*剩余数组中最大的数字 < target,进行下一次循环
    class Solution {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        int cur = 0;
    
        public List<List<Integer>> fourSum(int[] nums, int target) {
            Arrays.sort(nums);
            dfs(nums, target, 0);
            return result;
        }
    
        private void dfs(int[] nums, int target, int begin){
            if(list.size() == 4){
                if(cur == target){
                    result.add(new ArrayList<>(list));
                }
                return;
            }
            for(int i = begin; i < nums.length; i++){
                if(nums.length - i < 4 - list.size()){
                    return;
                }
                if(i > begin && nums[i] == nums[i - 1]){
                    continue;
                }
                if(i < nums.length - 1 && cur + nums[i] + (3 - list.size()) * nums[i + 1] > target){
                    return;
                }
                if(i < nums.length - 1 && cur + nums[i] + (3 - list.size()) * nums[nums.length - 1] < target){
                    continue;
                }
                cur += nums[i];
                list.add(nums[i]);
                dfs(nums, target, i + 1);
                list.remove(list.size() - 1);
                cur -= nums[i];
            }
        }
    }
    
  • 相关阅读:
    iframe与动作连处理
    selenium其他自动化操作
    使用seleniun模拟登陆qq空间
    selenium基本使用
    验证码识别 云打码之古诗文网验证识别
    图片爬取基础
    centos8下LAMP搭建Nextcloud
    浅谈centos8与centos7
    DHCP服务器配置及测试
    使用Apache服务器实现Nginx反向代理
  • 原文地址:https://www.cnblogs.com/crazyBlogs/p/13159080.html
Copyright © 2011-2022 走看看