LeetCode 18. 四数之和

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(log⁡n),排序使用

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;
}
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jarlen John

谢谢你给我一杯咖啡的温暖

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值