LeetCode 15. 3Sum C++

版权声明:个人整理,仅供参考,请勿转载,如有侵权,请联系[email protected] https://blog.csdn.net/mooe1011/article/details/88629607

Given an array nums of n integers, are there elements abc in nums such that a + b + c= 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

方法一:

二分法,先排序,注意剪枝,前后各一个指示,中间的靠二分法搜索。速度比较慢,但空间复杂度高于90%

class Solution {
public:
	vector<vector<int>> threeSum(vector<int>& nums) {
		int sz = nums.size();
		vector<vector<int>> res;
		sort(nums.begin(), nums.end());
		for (int i = 0; i < sz - 2; i++) {
			if (i > 0 && nums[i - 1] >= 0)    //{0,0,0,0}
				break;
			while (i > 0 && nums[i] == nums[i - 1])
				i++;
			for (int k = sz - 1; k > i + 1; k--) {
				while (k > i + 2 && nums[k] == nums[k - 2]) {
					k--;
				}

				if (nums[i] + 2 * nums[k] < 0)    //剪枝{-4,*,1}
					break;
				if (nums[i] * 2 + nums[k] > 0)    //剪枝{-2,*,5}
					continue;

				
				int l = i, r = k;
				while (l < r) {
					int j = (l + r) / 2;
					if (j == l || j == r)
						break;

					int tmp = nums[i] + nums[j] + nums[k];

					if (tmp == 0) {
						res.push_back({ nums[i] , nums[j] , nums[k] });

						if (nums[k] == nums[k - 1])
							k--;
						break;
					}
					else if (tmp > 0)
						r = j;
					else
						l = j;
				}
			}
		}
		return res;
	}
};

方法二:

同样先排序,同样剪枝,用j记录使得三数和最接近0的数的中间位置,时间快于86%的人,空间高于93%

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {    
        int sz = nums.size();
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        int j = (sz - 1) / 2;

        for (int i = 0; i < sz - 2; i++) {
            if (i > 0 && nums[i - 1] >= 0) //{0,0,0,0}
                break;
            while (i > 0 && nums[i] == nums[i - 1])
                i++;
            for (int k = sz - 1; k > i + 1; k--) {
                while (k > i + 2 && nums[k] == nums[k - 2]) {
                    k--;
                }
                if (nums[i] + 2 * nums[k] < 0)   //{-5,*,2}
                    break;
                if (nums[i] * 2 + nums[k] > 0)	//{-2,*,5}
                    continue;

                if (j <= i)    //确保j在i和k之间
                    j = i + 1;
                else if (j >= k)
                    j = k - 1;


                int tmp = nums[i] + nums[k];

                if (tmp + nums[j] == 0) {
                    res.push_back({ nums[i] , nums[j] , nums[k] });                   
                }
                else if (tmp + nums[j] > 0) {
                    while (nums[j - 1] > -tmp)
                        j--;
                    if (nums[j - 1] == -tmp && j - 1 > i) {
                        res.push_back({ nums[i] , nums[j - 1] , nums[k] });
                    }
                }
                else {
                    while (nums[j + 1] < -tmp)
                        j++;
                    if (nums[j + 1] == -tmp && j + 1 < k) {
                        res.push_back({ nums[i] , nums[j + 1] , nums[k] });
                    }
                }
                if (nums[k] == nums[k - 1])
                    k--;
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/mooe1011/article/details/88629607
今日推荐