【LeetCode刷题-数组】--18.四数之和

18.四数之和

【LeetCode刷题-数组】--18.四数之和_第1张图片

方法:排序+双指针

先对数组进行排序,使用两重循环分别枚举前两个数,然后在两重循环枚举到的数之后使用双指针枚举剩下的两个数

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        if(nums == null || nums.length < 4){
            return ans;
        }
        Arrays.sort(nums);
        int len = nums.length;
        for(int i = 0; i < len - 3; i++){
            //同一循环中,当前元素与上一个元素相同,则跳过当前元素
            if(i > 0 && nums[i] == nums[i - 1]){  
                continue;
            }
            //确定第一个数之后,如果nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target
            //说明此时剩下的三个数无论取什么值,四数之和一定大于target,因此退出第一重循环
            if((long) nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target){
                break;
            }
            //确定第一个数之后,如果nums[i] + nums[len-3] + nums[len-2] + nums[len-1] < target
            //说明此时剩下的三位数无论取什么值,四数之和一定小于target,因此第一重循环直接进入下一轮,枚举nums[i+1]
            if((long) nums[i] + nums[len-3] + nums[len-2] + nums[len-1] < target){
                continue;
            }
            //使用两层循环分别枚举两个数,然后在两重循环枚举到的数之后使用双指针枚举剩下的两个数
            for(int j = i + 1;j < len - 2 ; j++){
                //同一循环中,当前元素与上一个元素相同,则跳过当前元素
                if(j > i + 1 && nums[j] == nums[j - 1]){
                    continue;
                }
                //确定前两个数之后,如果nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target
                //说明此时剩下的里两个数无论取什么值,四数之和一定大于target,因此退出第二重循环
                if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
                    break;
                }
                //确定前两个数之后,如果nums[i] + nums[j] + nums[len-2] + nums[len -1] < target
                //说明此时剩下的两个数无论取什么值,四数之后一定小于target,第二重循环直接进入下一轮,枚举nums[j+1]
                if((long) nums[i] + nums[j] + nums[len-2] + nums[len -1] < target){
                    continue;
                }
                //在两重循环枚举到的数之后使用双指针枚举剩下的数
                int left = j + 1,right = len - 1;
                while(left < right){
                    long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
                    if(sum == target){
                        ans.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
                        while(left < right && nums[left] == nums[left + 1]){
                            left++;
                        }
                        left++;
                        while(left < right && nums[right] == nums[right - 1]){
                            right--;
                        }
                        right--;
                    }else if(sum < target){
                        left++;
                    }else{
                        right--;
                    }
                }
            }
        }
        return ans;
    }
}

你可能感兴趣的:(#,数组,leetcode,算法)