给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 示例 2:

输入:nums = [] 输出:[] 示例 3:

输入:nums = [0] 输出:[]

解法一(暴力破解):

import UIKit

var str = "Hello, playground"

var list = [-1,0,1,2,-1,-4]

let listLength = list.count
var result:[[Int]] = []
var sumStrings: [String] = []

for i in 0..<listLength - 2 {
    for j in (i + 1)..<listLength - 1 {
        for k in (j + 1)..<listLength {
            let sumArray = [list[i], list[j], list[k]].sorted()
            let sum = list[i] + list[j] + list[k]
            let sumString = sumArray.reduce("") { (result, current) -> String in
                return "\(result)\(current)"
            }

            if sum == 0 && !sumStrings.contains(sumString) {
                result.append([list[i], list[j], list[k]])
                sumStrings.append(sumString)
            }
        }
    }
}

print(result)

解法二:排序后双指针

class Solution {
    func threeSum(_ nums: [Int]) -> [[Int]] {
        let listLength = nums.count
        var result:[[Int]] = []
        if listLength < 3 {
            return result
        }
        var list = nums.sorted() // 升序排序
        var sumStrings: [String] = []

        for i in 0..<listLength - 2 {
            var k = listLength - 1
            for j in (i + 1)..<listLength - 1 {
                var sum = list[i] + list[j] + list[k]
                while sum > 0 && k > j {
                    k -= 1
                    sum = list[i] + list[j] + list[k]
                }
                if k <= j {
                    break
                }
                let sumArray = [list[i], list[j], list[k]].sorted()
                let sumString = sumArray.reduce("") { (result, current) -> String in
                    return "\(result)\(current)"
                }
                if sum == 0 && !sumStrings.contains(sumString) {
                    result.append([list[i], list[j], list[k]])
                    sumStrings.append(sumString)
                }
            }
        }    

        return result
    }
}

上述解法的缺点是去重的判断上,需要用到额外的空间和字符串转换来判断。

解法三:基于解法二,优化去重的判断,重点在于数组已经排好序了。

class Solution {
    func threeSum(_ nums: [Int]) -> [[Int]] {
        let listLength = nums.count
        var result:[[Int]] = []
        if listLength < 3 {
            return result
        }
        var list = nums.sorted() // 升序排序
        var sumStrings: [String] = []

        for i in 0..<listLength - 2 {
            if list[i] > 0 {
                break
            }
            // 去重
            if i > 0 && list[i] == list[i - 1] {
                continue
            }
            var k = listLength - 1
            for j in (i + 1)..<listLength - 1 {
                if list[j] + list[i] > 0 {
                    break
                }
                // 去重
                if j > (i + 1) && list[j] == list[j - 1] {
                    continue
                }
                var sum = list[i] + list[j] + list[k]
                while sum > 0 && k > j {
                    k -= 1
                    sum = list[i] + list[j] + list[k]
                }
                if k <= j {
                    break
                }
                if sum == 0 {
                    result.append([list[i], list[j], list[k]])
                }
            }
        }    

        return result
    }
}

标签: swift

添加新评论

0%