LeetCodeSwift 1.Two Sum - 两数之和

题目

两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1] 

思路

最简单粗暴就是2个for循环,找到符合条件的就加入数组,最后返回数组,这样时间复杂度是O(n²)
不过我考虑优化一下,就是多创建一个数组,把已经遍历过的元素加到已经循环过的数组里面,然后只需要遍历原数组和已经遍历的数组,可以减少循环次数
代码:

func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
    var sums: [Int] = []
    var hasNums = [Int: Int]()
    for (index, num) in nums.enumerated() {
        var hasAppendNum: (Int, Int)?
        for (hasIndex, hasNum) in hasNums {
            if num + hasNum == target {
                sums.append(hasIndex)
                sums.append(index)
                hasAppendNum = (hasIndex, hasNum)
                break
            }
        }
        if hasAppendNum != nil {
            hasNums.removeValue(forKey: hasAppendNum!.0)
        } else {
            hasNums[index] = num
        }
    }
    return sums
}

结果是能够通过 playground,但是提交 LeetCode 超时,应该是时间复杂度太高,所以还需要继续优化代码

想到可以直接用 Dictionary 的 key 作为数字,这样可以快速查找是否存在, LeetCode 通过。
此方法时间复杂度为O(n),空间复杂度为O(n)
代码:

func twoSum2(_ nums: [Int], _ target: Int) -> [Int] {
    var sums: [Int] = []
    var hasNums = [Int: Int]()
    for (index, num) in nums.enumerated() {
        var hasAppendNum: Int?
        if let hasIndex = hasNums[target - num] {
            sums.append(hasIndex)
            sums.append(index)
            hasAppendNum = hasIndex
        }
        if hasAppendNum != nil {
            hasNums.removeValue(forKey: hasAppendNum!)
        } else {
            hasNums[num] = index
        }
    }
    return sums
}

最后完成的代码链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容