【算法设计与分析作业题】第六周:15. 3Sum

题目

C++ solution

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    	vector<vector<int>> result;
    	sort(nums.begin(), nums.end());

    	if (nums.size() <= 2 || nums.back() < 0 || nums.front() > 0)
    	{
    		return {};
    	}

    	for (int i = 0; i < nums.size() - 2, nums[i] <= 0; ++i) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            
            int tar = 0 - nums[i];
            for (int j = i + 1, k = nums.size() - 1; j < k; ) {
                if (nums[j] + nums[k] == tar) {
                    result.push_back({nums[i], nums[j], nums[k]});
                    while (j < k && nums[j] == nums[j + 1]) ++j;
                    while (j < k && nums[k] == nums[k - 1]) --k;
                    ++j; --k;
                } else if (nums[j] + nums[k] < tar) ++j;
                else --k;
            }
        }
        return result;
    }
};

简要题解

  1. 首先对原数组进行排序;
  2. 若数组长度小于3或有序数组的第一个数大于0或最后一个数小于0,则没有和为0的三个数;
  3. 然后开始遍历排序后的数组。当遍历到倒数第二个数或遇到正数时就结束循环,因为有序数组一个正数后面的数字都是正数,就永远不会出现和为0的情况了。
  4. 由于题目要求找出不同的数组,处理方法是从第二个数开始,如果和前面的数字相等,就跳过。
  5. 对于遍历到的数,用0减去这个数得到一个 target,用两个下标分别指向该数字之后的数组首尾两个数,如果两个数之和正好为 target,则将这三个数一起存入结果中,然后跳过重复数字;如果两个数之和小于 target,则将左边的下标递增,使得指向的数字增大一些;同理,如果两个数之和大于 target,则将右边的下标递减,使得指向的数字减小一些。

猜你喜欢

转载自blog.csdn.net/For_course/article/details/83053471