LeetCode----Two Sum

95 篇文章 0 订阅
93 篇文章 0 订阅

Two Sum

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2


分析:

从数组中找数。要点,不能暴力搜索,数组可能会很大,可以使用hash。我使用的python的set方式,set内部是使用hash的,所以不会超时。


代码:

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        snums = set(nums)
        for i, v in enumerate(nums):
            if target - v in snums and target - v in nums[i+1:]:
                return [i + 1, nums[i+1:].index(target - v) + i + 2]


其他从Discuss中看到的代码:

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        if len(nums) <= 1:
            return False
        buff_dict = {}
        for i in range(len(nums)):
            if nums[i] in buff_dict:
                return [buff_dict[nums[i]], i+1]
            else:
                buff_dict[target - nums[i]] = i+1


vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> hash;
    vector<int> res(2, 0);
    for (int i = 0; i < nums.size(); i++) {
        if (hash.find(target - nums[i]) != hash.end()) {
            res[0] = hash[target - nums[i]], res[1] = i + 1;
            return res;
        }
        hash[nums[i]] = i + 1;
    }
}

----------------------------------------------------------------------------------------------------------------------------------------------------

[2016-4-18增:排序+遍历的解法,思路from数学之美]

换个角度思考这道题,假如我们已经有了这个数组的任意两个元素之和的有序数组(长度为N^2)。那么利用二分查找法,只需要用O(2logN)的时间就可以找到这个值。

当然,我们并不能直接去计算这个有序数组,因为它需要O(N^2)的时间。但这个思考可以启发我们:可以直接对两个数字的和进行一个有序的遍历,从而降低算法的时间复杂度。

首先对数组进行排序,时间复杂度为O(NlogN)。

然后令i=0,j=n-1,看arr[i] + arr[j]是否等于Sum,如果是,则结束。如果小于Sum,则i=i+1,如果大于Sum,则j=j+1.

这样只需要在排序好的数组上遍历一次,就可以得到最后的结果,遍历的时间复杂度为O(N)。两步加起来的时间复杂度为O(NlogN).


根据上面的这个思路,我们来解决Two Sum这道题。

首先我们要对输入数组nums进行排序,这里有一个问题,在找到两个元素和等于target后,程序要求并不是返回这两个数,而是要求返回这两个元素对应的下标。于是,我这里将nums中的元素转换成了一个个的tuple,tuple包含原数组元素值和元素对应的下标,然后对包含tuple的数组按照元素值进行排序。这样我能够在查找到两个元素后仍能够找到这两个元素在nums中对应的下标。


代码如下:

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        # 将nums转换成包含一个个tuple的list,每个tuple为nums中元素值和对应的下标:(value,index)
        dummynums = [(v, i) for i, v in enumerate(nums)]
        # 对dummynums按照元素值进行排序
        dummy_soted = sorted(dummynums, key=lambda x:x[0])
        # 下面的的循环即用的是刚刚介绍的遍历思路
        l, r = 0, len(nums) - 1
        while l < r:
            if dummy_soted[l][0] + dummy_soted[r][0] == target:
                return [dummy_soted[l][1], dummy_soted[r][1]]
            elif  dummy_soted[l][0] + dummy_soted[r][0] > target:
                r -= 1
            else:
                l += 1
        return None


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值