三数之和
三数之和
这道题和
三道题思路一样,都可以用双指针的方式和hash表的方式进行优化。
当数字个数越多hash的方式优势越明显,四数之和明显优于双指针
点:如何去掉重复的数据即不包含重复的三元组
双指针
固定一个数据寻找另外两个数据就退化为了两数之和
每次加入元素的时候比较其与相邻元素的关系如果相等就跳过这个元素(去重)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
// hash
// 回顾两数之和,给定一个k求解两个数之和为k
// 用O(n)时间构建一个map,key为当前值,value为所需值
// O(n)时间构造字典key - value (key + value == 0)
// 双指针循环
// 重复数据
int len = nums.size();
if(len < 3) return {};
sort(nums.begin(), nums.end());
vector<vector<int>> rst = {};
int tag = 0;
for(int i=0; i<len;++i){
if(nums[i]>0) return rst;
if(i>0 && (nums[i] == nums[i-1])) continue;
int low = i+1; //
int high = len-1;
tag = 0 - nums[i];
while(low<high){
if(nums[low] + nums[high] == tag) {
rst.push_back({nums[i], nums[low], nums[high]});
while(low < high && nums[low] == nums[low+1]) ++low;//去重
while(low < high && nums[high] == nums[high-1]) --high;
++low;
--high;
}
else if(nums[low] + nums[high] > tag) --high;
else ++low;
}
}
return rst;
}
};
hash
LeetCode-探索卡片
三数之和和四数之和,探索卡片里有非常好的解释
以三数之和为例子
三数之和相对于二数之和就是,我确定一个数sum 那么就用二数之和找到这个 k - sum就可以了
四数之和同理
仍要注意去重(相同continue跳过)
python代码如下
class Solution:
def twoSum(self, nums, target, l, r):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
n = len(nums[l : r+1])
if n < 2:
return list()
start = nums[l - 1]
dict1 = dict()
ret = list()
for i in range(l, r+1):
other = target - nums[i]
if other in dict1:
ret.append([start, other, nums[i]])
dict1[nums[i]] = i
return ret
# nums[l...r] 中返回 a+b+c=target
def threeSum(self, nums, target, l, r):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
n = len(nums[l : r+1])
if n < 3:
return list()
start = nums[l-1]
ret = list()
for i in range(l, r+1):
if nums[i] > 0 and target <= 0:
break
if (i >= l+1 and nums[i] == nums[i-1]):
continue
ll = self.twoSum(nums, target-nums[i], i+1, r)
if (ll == list()):
continue
for i in ll:
i.insert(0, start)
ret.append(i)
return ret
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
n = len(nums)
if n < 4:
return []
nums.sort()
ret = set()
for i in range(n):
ll = self.threeSum(nums, target-nums[i], i+1, n-1)
if ll == list():
continue
for l in ll:
ret.add(tuple(l))
return list(ret)