[LeetCode] 18、四数之和

题目描述

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
满足要求的四元组集合为:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]

解题思路

CSDN搜索“之和”,可以看到类似的题目。

本题在15、三数之和的基础上加了一层for循环,思路是一样的

  • 排序 + 双指针
    • 使用四个指针(a<b<c<d)。固定最小的ab在左边,c=b+1d=_size-1。移动两个指针包夹求解。 保存使得nums[a]+nums[b]+nums[c]+nums[d]==target的解。和偏大时d左移,偏小时c右移。cd相遇时,表示以当前的ab为最小值的解已经全部求得,b++,进入下一轮b循环,当b循环结束后,a++,进入下一轮a循环。 即(a在最外层循环,里面嵌套b循环,再嵌套双指针c,d包夹求解)。
    • 要使用双指针的方法,排序是必须要做der~。 时间复杂度 O ( N l o g N ) O(NlogN)
    • 上面的解法存在重复解的原因是因为移动指针时可能出现重复数字的情况。所以我们要确保移动指针后,
      对应的数字要发生改变才行哦。

参考代码

class Solution{
	public: 
	vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int> > res;
        if(nums.size()<4)
            return res;
            
        sort(nums.begin(),nums.end());
        int a, b, c, d, _size = nums.size();
        for(a = 0; a <= _size-4; a++){
        	if(a > 0 && nums[a] == nums[a-1]) 
                continue;      //确保nums[a] 改变了
        	for(b = a+1; b <= _size-3; b++){
        		if(b > a+1 && nums[b] == nums[b-1])
                    continue;   //确保nums[b] 改变了
            
        		c = b + 1, d = _size - 1;
        		while(c < d){
        			if(nums[a]+nums[b]+nums[c]+nums[d] < target)
        			    c++;
        			else if(nums[a]+nums[b]+nums[c]+nums[d] > target)
        			    d--;
        			else{
        				res.push_back({nums[a], nums[b], nums[c], nums[d]});
        				while(c < d && nums[c+1]==nums[c])      //确保nums[c] 改变了
        				    c++;
        				while(c < d&&nums[d-1]==nums[d])      //确保nums[d] 改变了
        				    d--;
        				c++;
        				d--;
					}
				}
			}
		}
		
		return res;
    }
};
发布了415 篇原创文章 · 获赞 603 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/ft_sunshine/article/details/104056232
今日推荐