三数之和

LIZHAO LeetCode
阅读量 0 评论量 0

Leetcode:三数之和

掌握程度:★ ★ ☆

只想到了暴力发,三成for循环暴力。

看题解,排序 + 双指针。

看见排序就复习了一下快速排序,真的是很容易忘记。

快速排序

挖坑填数 + 分治的思想。

void quickSort(vector<int> &nums, int left, int right) {
    if (left < right) {
        int id = partition(nums, left, right);
		//分别递归基准的左边和右边。
        quickSort(nums, 0, id - 1);
        quickSort(nums, id + 1, right);
    }
}

int partition(vector<int> &nums, int left, int right) {
    //选取一个基准数
    int base = nums[left];
	//将大于基准数的放在右边,小于基准数的放在左边,并返回基准位置。
    while (left < right) {
        while (left < right && nums[right] >= base) {
            right--;
        }
        nums[left] = nums[right];
        while (left < right && nums[left] <= base) {
            left++;
        }
        nums[right] = nums[left];
    }
    nums[left] = base;
    return left;
}

排序+双指针

排序确保,相同的元素排在一起,就可以通过相邻两个元素是否相等来去重。

vector<vector<int>> threeSum(vector<int>& nums) {
	//排序用上面的快速排序,时间超限了,std的排序比较快。
    std::sort(nums.begin(),nums.end());

    int len = nums.size();
    std::vector<std::vector<int>> ans;
    for (int i = 0; i < len; ++i) {
        if (i > 0 && nums[i] == nums[i-1]){continue;}
        int left = i + 1;
        int right = len - 1;
        while (left<right){
            int res = nums[i]+nums[left]+nums[right];
            if (res == 0){
                ans.push_back({nums[i],nums[left],nums[right]});
                left++;
                right--;
                //去重,若左边当前的数,和上一个数相同,那么这个数不用再计算了。
                while (left < right && nums[left] == nums[left-1]){
                    left++;
                }
                //去重,同理
                while (left<right && nums[right] == nums[right+1]){
                    right--;
                }
                continue;
            }else if (res>0){
                right--;
            }else if (res <0){
                left++;
            }
        }
    }
    return ans;
}
喵~