leetcode [18. 四数之和]

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

因为题目没给数据规模,在经历过一次WA,一次TLE和无数次内心博弈后,最终屈服看答案,虽然说官方题解没有给出什么高深的算法,不过一码归一码,我觉得这题的双指针思想还是不错的。

将数组排序后就可以进行枚举了,他要求四个数之和等于target,通过题解中的双指针思想我们只需要枚举两个数,然后通过双指针来确定最后的答案,可以实现将暴力的O(n^4)降到O (n^3)

双指针就是将数组排序后如果两个指针指向的数和枚举的两个数之和等于target,那这就是一个答案,记录后将双指针指向一个新的位置继续枚举;如果大于target,就把右指针往做挪挪;如果小于target,就把左指针往右挪挪;再写的过程中在加入一些去重操作就行了

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ans;
        int n = nums.size();
        sort(nums.begin(),nums.end());
        for (int i = 0; i < n; ){
            for (int j = i+1; j < n; ){
                int left = j+1,right = n-1;
                while(left < right){
                    if (nums[i]+nums[j]+nums[left]+nums[right] == target){
                        ans.push_back({nums[i],nums[j],nums[left],nums[right]});
                        left++,right--;
                        while(left < n && nums[left] == nums[left-1]) left++;
                        while(right >= 0 && nums[right] == nums[right+1]) right--;
                    }
                    else if (nums[i]+nums[j]+nums[left]+nums[right] > target){
                        right--;
                        while(right >= 0 && nums[right] == nums[right+1]) right--;
                    }else{
                        left++;
                        while(left < n && nums[left] == nums[left-1]) left++;
                    }
                }
                j++;
                while(j < n && nums[j] == nums[j-1]) j++;
            }
            i++;
            while(i < n && nums[i] == nums[i-1]) i++;
        }
        return ans;
    }
};
"没有天赋异禀,那就加倍努力"
原文地址:https://www.cnblogs.com/Beic233/p/13772050.html