[LeetCode]1 Two Sum(C++,Python实现)

LeetCode OJ的第一题,如果有问题或者给我指点欢迎来信讨论[email protected]

题目描述

LeetCode OJ的第一题,题目描述如下:

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.


给定一个序列,若其中存在两个元素之和为给定的数字target。注意返回的两个序列要求“not zero-based”,也就是从1开始计数而不是像数组一样从0下标开始。

思路1

首先给定的序列是无序的,如果序列有序(设已经从小到大排序),那么设一个下标A从头开始,另一个下标B从尾开始,如果二者之和小于target,说明两者的和不够大,由于B下标指向的是当前可能情况下序列的最大值(因为B开始指向最大值,而B的每次减小都是因为B加上当前可能情况下序列最小的值已经超过了target),所以下标A增加,如果二者之和等于target,则得到所需结果。如果二者之和大于target,说明二者之和大了,由于A下标指向的是当前可能情况下序列的最小值(因为A开始指向最小值,而A的每次增加都是因为A加上当前可能情况下序列的最大值已经不够target),所以下标B减小。
这种方法在两个下标遍历的时候只有O(n)的复杂度,但是在排序时候要O(nlgn)复杂度,所以总的复杂度为O(nlgn)。

思路2

上面思路的瓶颈在于排序,能否不需要排序而直接找到结果呢?
如果存在着一对解m, n,设m在序列中排在n的前面。我们从头到尾遍历该序列,用数据结构S存储已经遍历过的数据。遍历到m时候,寻找target-m是否在S中,这时候还是不在。但是遍历到n的时候就发现target-n,也就是m,在S中,这时候我们就得到了解。该方法的时间复杂度为O(n),但是可能需要额外O(n)的存储空间。而数据结构要很方便于查询,所以使用了字典(C++中用map,Python中用dict,存储数据以及下标),查询复杂度为O(1)。

注意事项

返回的值前一个要比后一个小。
要注意存在着两个元素相同的情况,如4,4,target=8。这时候不要返回相同的下标

代码

Python, O(nlgn)
def twoSum(self, num, target):
        tmp_num = num[:]
        tmp_num.sort()
        index1 = 0
        index2 = len(tmp_num)-1
        while index1 < index2:
            tmp_target = tmp_num[index1] + tmp_num[index2]
            if tmp_target == target:
                break
            elif tmp_target > target:
                index2 -= 1
            else:
                index1 += 1
        if index1 == index2:
            return (-1, -1)
        else:
            ans1 = num.index(tmp_num[index1])
            ans2 = num.index(tmp_num[index2])
            if ans2 != ans1:
                # not zero based
                return (min(ans1, ans2)+1, max(ans1, ans2)+1)
            else:
                ans2 = num[ans1+1:].index(tmp_num[index2])
                return (ans1+1, ans1+1+ans2+1)

Python,O(n)
def twoSum1(self, num, target):
        tmp_num = {}
        for i in range(len(num)):
            if target - num[i] in tmp_num:
                # here do not need to deal with the condition i = target-i
                return (tmp_num[target-num[i]]+1, i+1)
            else:
                tmp_num[num[i]] = i
        return (-1, -1)

C++,O(n)
class Solution {
public:
    vector twoSum(vector &numbers, int target) {
        map searched;
		vector res;
		for (int i = 0; i < numbers.size(); ++i){
			if (searched.count(target - numbers[i])){
				res.push_back(searched[target - numbers[i]]+1);
				res.push_back(i+1);
				return res;
			} else {
				searched[numbers[i]] = i;
			}
		}
		res.push_back(-1);
		res.push_back(-1);
		return res;
    }
};


你可能感兴趣的:(算法,LeetCode)