leetcode-18. 4Sum

15题的变式

题意:

给出一个数组和目标和target,在数组中找到四个数,使他们相加之和为target

我的思路: 双层循环(最优解法即为O(N^2^))

51%, O(N^2^)

类似15题,先排序,外层是两层循环,内层是两个指针找剩余两个数的和

步骤:
1. 数组排序
2. 双层遍历数组nums[i]和nums[j],如果i>0且nums[i]不等于nums[i - 1]时,继续二层循环;当==j> i + 1==(表示不是改变i重新循环后的第一个数)且nums[j]不等于nums[j - 1]时,继续下面的操作
3. 设置指针low = j + 1,high = length - 1
3. 当low和high位置的数相加>target- nums[i] - nums[j]时,high–;
4. 当low和high的数相加小于时,low++;

5. 相等时,将目前的组合加入result,并且检测low之后的数,若相同low++跳过,high之前的数,若相同high–跳过

改进:效率提高至82%!!!

==由此可见,涉及到多层循环的,提前判断避免不必要的进入内循环是非常必要的。==

提高效率可以加上几个判断使得非法值一开始就能检测出,避免不必要的循环
- 当nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target或者nums[i]+nums[j]+nums[j+1]+nums[j+2]>target时,证明该趟外层循环最小的和都比target大,跳出;
- nums[i]+nums[nums.length-1]+nums[nums.length-2]+nums[nums.length-3]

改进后的代码:

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res=  new ArrayList<>();
        int len = nums.length;
        if (len < 4) {
            return res;
        }
        Arrays.sort(nums);
        for (int i = 0; i < len - 3; i++) {

            if(nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target)continue;
            if(nums[i]+nums[nums.length-1]+nums[nums.length-2]+nums[nums.length-3]<target)continue;

            if (i > 0 && nums[i - 1] == nums[i]) {
                continue;
            }
            for (int j = i + 1; j < len - 2; j++) {
                if(nums[i]+nums[j]+nums[j+1]+nums[j+2]>target)continue; //second candidate too large
                if(nums[i]+nums[j]+nums[nums.length-1]+nums[nums.length-2]<target)continue; //second candidate too small
                if (j > i + 1 && nums[j - 1] == nums[j]) {
                    continue;
                }
                int low = j + 1;
                int high = len - 1;
                int temp = target - nums[i] - nums[j];
                while (low < high) {
                    int sum = nums[low] + nums[high];
                    if (sum < temp) {
                        low++;
                    }
                    else if (sum > temp) {
                        high--;
                    }
                    else {
                        res.add(Arrays.asList(nums[i], nums[j], nums[low], nums[high]));
                        while (low < high && nums[low + 1] == nums[low]) {
                            low++;
                        }
                        while (low < high && nums[high - 1] == nums[high]) {
                            high--;
                        }
                        low++;
                        high--;
                    }
                }
            }
        }
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/NNnora/article/details/81481308
今日推荐