LeetCode系列:1 Two Sum

Q:Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

E:给一个整型数组和一个数字,如果在整型数组中能有两个数字(每个数字仅可使用一次)相加和为该数字,那么请输出这两个数字在数组中的下标

你可以假设每一个输入都有一个确切的解,并且不可以使用同一个元素两次。

e.g.
数组 nums = [2,7,11,15]
目标 target = 9
2+7=9,所以返回27在数组中的下标,下标分别为01,所以输出:[0,1]

A:
Approach 1:

最简单最先想到的应该就是遍历,外层循环从第一个元素开始,内层循环从外层循环后一个元素开始,比如[2,7,11,15],外层循环从2开始,内层循环从7开始,一个一个遍历。

class Solution {
    func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
        for i in 0..<nums.count {
            for j in i+1..<nums.count {
                if nums[i] + nums[j] == target {
                    return [i,j]
                }
            }
        }
        return []
    }
}
Complexity Analysis:
  • 时间复杂度: O(n²)。外层循环n次,内层循环(n+1)/2次,总循环n(n+1)/2次,忽略低次项,故时间复杂度为 O(n²)。(LeetCode:572 ms)
  • 空间复杂度:O(1)。无需额外附加空间,所以为常数次项O(1)。

Approach 2:

匹配问题可以通过Hash Table来解决,我们将给定数组的所有当成key,然后将对应的下标当成value组成一个新的数组:

[2:0,7:1,11:2,15:3]

然后开始遍历,将target=9减去每一个key得到一个index,如果index存在于剩余的key中,则获取当前key的value和index的value。
如:第一个Dictionary:[2:0],9-2=7,剩余的Dictionary存在一个key为7的Dictionary,所以获得[2:0],[7:1],所以当前解是:[0,1]

class Solution {
    func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
        var dic : [Int : Int] = [:]
        for i in 0..<nums.count {
            dic.updateValue(i, forKey: nums[i])
        }

        for (key, value) in dic {
            let index = target - key
            if dic.keys.contains(index) && value != dic[index] {
                return [value, dic[index]!]
            }
        }
        
        return []
    }
}

Complexity Analysis:
  • 时间复杂度: O(n)。
  • 空间复杂度:O(n)。

Warning: Approach 2方法存在一个问题,当数组存在两个相同数字时,且这两个数字刚好为解时,这个算法会失效。如:nums = [3,3,5],target = 6.该算法得不出正确解,因为Dictionary会将存在的key的值进行更新而不是再插入一次,所以3为key的Dictionary只有一个。


Approach 3:

Approach 2是一次性将数组所有元素都转成Dictionary,但是这样就会有一个问题,当存在值相等的元素,且这俩元素刚好为解的问题,那有没有办法解决这个问题呢,当然有,不要一次性转换不就好了么,边遍历边给Dictionary加元素。

class Solution {
    func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
        var dic : [Int : Int] = [:]
        for (index, value) in nums.enumerated() {
            if let toIndex = dic[target - value] {
                return [toIndex, index]
            }
            dic[value] = index//未命中,则加入到Dictionary中
        }
        
        return []
    }
}
Complexity Analysis:
  • 时间复杂度: O(n)。(LeetCode:40ms)
  • 空间复杂度:O(n)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值