18. 四数之和
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
解题思路:排序+双指针
总体思路同三数之和:15. 三数之和
需要注意一下几点:
1.边界情况的判断
2.去重
时间复杂度:O(n^3)
空间复杂度:O(logn),排序使用
Swift
func fourSum(_ nums: [Int], _ target: Int) -> [[Int]] {
guard nums.count > 3 else { return [] }
let nums = nums.sorted()
let cnt = nums.count
var results = [[Int]]()
for i in 0..<cnt-3 {
if i > 0 && nums[i] == nums[i-1] {
continue
}
if nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target {
break;
}
if nums[i] + nums[cnt - 3] + nums[cnt - 2] + nums[cnt - 1] < target {
continue;
}
for j in i+1..<cnt-2 {
if j > i+1 && nums[j] == nums[j-1] {
continue
}
var k=j+1, l = cnt-1
while k < l && k<cnt {
let sum = nums[i] + nums[j] + nums[k] + nums[l]
if sum == target {
results.append([nums[i], nums[j], nums[k], nums[l]])
while k < l && nums[k] == nums[k+1] {
k += 1
}
k+=1;
while k < l && nums[l] == nums[l-1]{
l -= 1
}
l -= 1
}else if sum < target {
k += 1
}else {
l -= 1
}
}
}
}
return results
}
OC
-(NSArray *)fourSum:(NSArray *)nums
target: (NSInteger)target {
NSMutableArray *result = @[].mutableCopy;
if (nums.count < 4) {
return result;
}
nums = [nums sortedArrayUsingComparator:^NSComparisonResult(NSNumber *obj1, NSNumber *obj2) {
return [obj1 compare:obj2];
}];
NSInteger cnt = nums.count;
for (NSInteger i=0; i<cnt-3; i++) {
if (i>0 && nums[i] == nums[i-1]) {
continue;
}
//若刚开始就比target大,则直接结束
if ([nums[i] integerValue] + [nums[i+1] integerValue] + [nums[i+2] integerValue]+ [nums[i+3] integerValue] > target) {
break;
}
if ([nums[i] integerValue] + [nums[cnt-3] integerValue] + [nums[cnt-2] integerValue] + [nums[cnt-1] integerValue] < target) {
continue;
}
for (NSInteger j=i+1; j<cnt-2; j++) {
if (j > i+1 && nums[j] == nums[j-1]) {
continue;
}
NSInteger k=j+1, l=cnt-1;
while (k < l) {
NSInteger s = [nums[i] integerValue] + [nums[j] integerValue] + [nums[k] integerValue] + [nums[l] integerValue];
if (s == target) {
[result addObject:@[nums[i], nums[j], nums[k], nums[l]]];
while (k<l && [nums[k] integerValue] == [nums[k+1] integerValue]) {
k++;
}
k++;
while (k<l && [nums[l] integerValue] == [nums[l-1] interval]) {
l--;
}
l--;
}else if(s < target) {
k++;
}else {
l--;
}
}
}
}
return result;
}