LeetCode上的两个和

时间:2015-05-04 00:40:54

标签: python

我试图做一个LeetCode问题:

  

给定一个整数数组,找到两个数字,使它们加起来   特定的目标号码。

     

函数twoSum应该返回两个数字的索引   它们加起来到目标,其中index1必须小于index2。   请注意,您返回的答案(index1和index2)都是   不是从零开始的。

     

您可以假设每个输入都只有一个解决方案。

     

输入:数字= {2,7,11,15},目标= 9输出:index1 = 1,index2 = 2

第一次尝试是使用两个for循环,这给了我O(n ^ 2),不幸的是它没有通过。因此我尝试使用:

target - current = index

并搜索字典中是否存在索引。

这是我的代码:

class Solution:
    def twoSum(self, nums, target):
        dic = {}

        #A number can appear twice inside the same index, so I use a list
        for i in xrange(0, len(nums)):
            try:
                dic[nums[i]].append(i)
            except:
                dic[nums[i]] = []
                dic[nums[i]].append(i)

        try:
            for items_1 in dic[nums[i]]:
                for items_2 in dic[target-nums[i]]:
                    if(items_1+1 != items_2+1):
                        l = []
                        if(items_2+1 > items_1+1):
                            l.append(items_1+1)
                            l.append(items_2+1)
                        else:
                            l.append(items_2+1)
                            l.append(items_1+1)
                        return l
        except:
            pass

我在本地开发了这个,并且我能够得到LeetCode抱怨的测试用例之一的正确结果:[ - 3,3,3,90],0

我得到的输出是[1,3],但是在LeetCode上它返回null,有人知道为什么会发生这种情况吗?

15 个答案:

答案 0 :(得分:12)

你想要这些内容:

#! python3

def two_sum(arr,targ):
    look_for = {}
    for n,x in enumerate(arr,1):
        try:
            return look_for[x], n
        except KeyError:
            look_for.setdefault(targ - x,n)

a = (2,7,1,15)
t = 9
print(two_sum(a,t))  # (1,2)

a = (-3,4,3,90)
t = 0
print(two_sum(a,t))  # (1,3)

在此您可以根据需要构建值字典。字典由您正在寻找的值键入,并且对于每个值,您可以跟踪其首次出现的索引。只要您达到满足问题的价值,您就完成了。循环只有一个。

唯一的另一个细节是为每个索引添加1以满足索引从1开始的荒谬要求。就像那个教你学习Python编程一样。

使用setdefault函数将密钥添加到字典中,因为如果密钥已经存在,您希望保留其值(最低索引)。

答案 1 :(得分:9)

def twosum(nums=(6, 7, 11, 15, 3, 6, 5, 3), target=6):
    lookup = dict(((v, i) for i, v in enumerate(nums)))
    return next(( (i+1, lookup.get(target-v)+1) 
            for i, v in enumerate(nums) 
                if lookup.get(target-v, i) != i), None)

我没有对此进行过广泛测试,但基本逻辑应该是合理的。该算法可分为两个阶段:

  1. 为nums中的所有索引,值对创建value->索引的字典。请注意,您可以使用具有不同索引的多个值。在这种情况下,最高索引将存储在字典中,较低索引将被覆盖。当然,这种行为可以修改,但我不相信它需要解决这个问题,因为问题陈述的一部分是:"您可以假设每个输入都只有一个解决方案。 #34;因此,每个输入都有一个唯一的输出,所以我们永远不必担心返回错误对"指数。

  2. 循环查看nums,将i作为索引,v作为值。检查target-v是否是我们创建的字典中的键,同时断言该键指向的值是 not i。如果这是真的,请返回元组i+1, lookup.get(target-v)+1

答案 2 :(得分:5)

我刚刚通过以下代码。为了获得有效的字典和笔记,只有一个解决方案。在逐个保存查找字典中的num时,搜索保存的查找字典中的target-num。当nums中有两个相同的值时,此方法可以节省空间并防止索引覆盖。

def twosum(self, nums, target):
    lookup = {}
    for cnt, num in enumerate(nums):
        if target - num in lookup:
            return lookup[target-num], cnt
        lookup[num] = cnt            

答案 3 :(得分:2)

这个答案使用从零开始的索引,因为这是索引的常规方式,而不是基于索引的索引。它还使用描述性变量名称。它是为了理解而写的。

def twosum_indices_linear(nums, target):
    numtoindexmap = {}
    for num1_index, num1 in enumerate(nums):
        num2 = target - num1
        try:
            num2_index = numtoindexmap[num2]
        except KeyError:
            numtoindexmap[num1] = num1_index
        else:
            return num1_index, num2_index

示例:

print(sorted(twosum_indices_linear([2, 7, 11, 15], 9)))
[0, 1]

print(sorted(twosum_indices_linear([3, 3], 6)))
[0, 1]

print(sorted(twosum_indices_linear([6, 7, 11, 15, 3, 6, 5, 3], 6)))
[4, 7]

信用:answer by joeg

答案 4 :(得分:0)

这是我的回答

class Solution:
    def twoSum(self, nums, target):
        ls = []
        for i in range(0, len(nums)):
            item = target - nums[i]
            nums[i] = "done"
            if item in nums:
                ls.append(i)
                ls.append(nums.index(item))
                return ls

答案 5 :(得分:0)

def twoSum(nums,target):
    k={value:index for index, value in enumerate(nums)} 
    # using dictionary comprehesion to create a dictionary that maps value to index 
    ans=[[j,k[target-x]] for j,x in enumerate(nums) if target-x in k] 
    # use list comprehension to create a set of answers; make sure no key error by using 'if target-x in k'
    ans=[x for x in ans if x[0] != x[1]] 
    # make sure the two indexes are not the same. E.g. twoSum([1,2,0],2) returns [[0,0],[0,1],[1,2],[2,1]]; and [0,0] is a wrong answer  
    return ans[0]

此解决方案具有时间效率(比leetcode上80%的解决方案更快),但需要大量内存。

答案 6 :(得分:0)

我喜欢

    def two_sum(arr,targ):
        look_for = {}
        for n,x in enumerate(arr,1):
            try:
               return look_for[x], n
            except KeyError:
               look_for.setdefault(targ - x,n)

上面,但是由于调用枚举对大型数组花费的时间太长,因此timedome失败。最好跳过枚举,只保留索引计数:

def findCombo(l,target):
    lookup = {}
    n = 0
    for x in l:
        try:
            return (n,lookup[x])
        except KeyError:            
            lookup.setdefault (target-x,n)
        n = n + 1

    return None

注意:Python timedome问题使用从0开始的索引

答案 7 :(得分:0)

一次通过哈希表

这可以一次性完成。 如何Teo?好吧,虽然它正在向散列中添加元素并将其插入,但还应该回头检查当前元素的补码是否已存在于散列中。如果存在,我们已经找到解决方法并立即返回。

复杂度:

时间复杂度: O(n) 。我们只遍历包含 n 个元素的列表。每次在表中查找仅花费 O(1) 时间。

空间复杂度: O(n) 。所需的额外空间取决于哈希表中存储的项目数,哈希表最多存储 n 个元素。

const nums = [2, 7, 11, 15];
const target = 9;


/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
let twoSum = function(nums, target) {
    let map = new Map;
    for (var i = 0; i < nums.length; i++) {
        let complement = target - nums[i];
        if (map.has(complement)) {
            return [map.get(complement), i]
        }
        map.set(nums[i], i);
    }
    throw new Error('No two sum solution'); 
}

console.log(twoSum(nums, target));

答案 8 :(得分:0)

如果仍在寻找此问题的javascript解决方案,

/** 
1. Two Sum

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].
* */

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
function twoSum(nums, target) {
  const numsObjs = {}; // create nums obj with value as key and index as value eg: [2,7,11,15] => {2: 0, 7: 1, 11: 2, 15: 3}

  for (let i = 0; i < nums.length; i++) {
    const currentValue = nums[i];

    if (target - currentValue in numsObjs) {
      return [i, numsObjs[target - currentValue]];
    }
    numsObjs[nums[i]] = i;
  }

  return [-1, -1];
}

console.log(twoSum([3,7,3], 6))

答案 9 :(得分:0)

我的单行解决方案:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        res=[[nums.index(val),nums[ind +1:].index(target-val)+ ind +1] for ind,val in enumerate(nums) if target -val in nums[ind +1:]]
        return res[0]

我可以解释它是否对某人感兴趣:)

答案 10 :(得分:0)

我认为上述解决方案看起来很复杂。

def twoSum(nums: List[int], target: int) -> List[int]:
   output = []
   for i in nums:
        for j in nums:
            if i + j == target and nums.index(i) != nums.index(j):
                output.append(nums.index(i))
                output.append(nums.index(j))
                return output

print(twoSum([2,7,11,15],9))
print(twoSum([3,2,4],6))

#输出

[0, 1]
[1, 2]

答案 11 :(得分:0)

@Shashank 的答案是正确的,但这个答案的结果从数组中的索引 1 开始,所以 leetcode 不会接受它。所以这里是相同的解决方案,只需简单更改即可从索引 0 开始数组。

class Solution:
    def twoSum(self,nums, target):
        lookup = dict(((v, i) for i, v in enumerate(nums)))
        return next(( (i, lookup.get(target-v)) 
            for i, v in enumerate(nums) 
                if lookup.get(target-v, i) != i), None)

答案 12 :(得分:-1)

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        r = []

        for i in range(len(nums)):
            temp = target - nums[i]
            if temp in r:
                return [i,nums.index(temp)]

            r.append(nums[i])

答案 13 :(得分:-1)

nums = [2, 7, 11, 15]
target = 9
l = []
x = 1
length = len(nums) - 1
for i in nums:
    l.append(nums.index(i))
    if (target - i) in nums[x:]:
       l.append(length - nums[::-1].index(target - i))
       break
    else:
       l = []
       x = x + 1
print(l)

请在此处检查提交的内容:https://www.youtube.com/watch?v=PeJtMogExbo

答案 14 :(得分:-1)

这是我在 C++ 中的回答。我希望你能把它转换成 python

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_set<int>s;
        vector<int>ans;
    int j =0;
    for(int i=0;i<nums.size();i++)
    {
        int temp = target -nums[i];
        //int tempInd = i ;
        if(s.find(temp)!=s.end()){
            //cout<<i<<" ";
             ans.push_back(i) ;
            for(int j=0;j<nums.size();j++)
            {
                if(temp == nums[j]){
                    //cout<<j<<endl;
                    ans.push_back(j) ;
                break;
                }
            }
        }
        s.insert(nums[i]);

    }
        return ans ;
    }
};