LeetCode:1. Two Sum解法(C,C++,Jave,Python)

来源:互联网 发布:qt for windows 编辑:程序博客网 时间:2024/05/16 09:53

采用C,C++,Jave,Python四种语言解答
C:3 ms
C++:19 ms
Java:6ms
Python:45ms
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.

译文:
给定一个整数数组,找出其中两个数满足相加等于你指定的目标数字。返回这两个数在数组中的索引。
你可以假定每种输入只有一个解决方案。

Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

UPDATE (2016/2/13):
The return format had been changed to zero-based indices. Please read the above updated description carefully.
返回的格式已经改变了从零开始的索引。请仔细阅读上述更新描述。
意思是index1必须要小于index2。


2.思路
最简单的解法是对数组进行两次遍历,分别得num1,num2,这样的解法时间复杂度为O(n2),可惜的是LeetCode直接来个Submission Result: Time Limit Exceeded。说明这种解法效率不高,不可取。
改善1:用头尾逼近法
改善2:hash哈希

头尾逼近法:
1:首先将数组1赋值到一个新的数组并将其排序得到数组2,数组2按从小到大的顺序;
2:分别建立头head标志指向数组2头部,即最小值;尾tail标志指向数组2尾部,即最大值;
3:开始遍历数组2,对头值+尾值得和与targe进行t比较
4:如果大于target,头前进,head++
5:如果小于target,尾后退,tail–
6:如果相等,可得到num1,num2这时再分别判断num1,num2在原数组1的位置即可;

hash哈希:
因为无论如何都要遍历一次数组,问题已经提示只有一对数的和为target。在遍历数组过程中,target和num1值已知,有没可能在一次遍历中就找到value2?
所以思路就是在遍历数组中,进行哈希表建立和对哈希表查询。
思路过程如下:
假如输入为[3, 2, 4], 6
**第1次循环:**nums[0]: 3 是否在 map::find(3) 中,没有,保存{6 - 3, 0}到map,此时map中有{3,0}
**第2次循环:**nums[1]: 2 是否在 map::find(2) 中,没有,保存{6 - 2, 1}到map,此时map有中{3,0}, {4, 1}
**第3次循环:**nums[2]: 4 是否在 map::find(4) 中,有,提取map键为4的值,为1,再提取当前i值,为2,将{1, 2}保存到结果中。


3.代码如下
C语言解法:用头尾逼近法(造个哈希表的轮子太麻烦了),耗时3ms

#include <stdio.h>#include <stdlib.h>#include <string.h>int comp(const void*a,const void*b){    return *(int*)a-*(int*)b;}int* twoSum(int* nums, int numsSize, int target) {    int* result = (int *)malloc(2 * sizeof(int));    memset(result, 0, 2 * sizeof(int));    int* tempNums = (int *)malloc(numsSize * sizeof(int));    int i;    for (i = 0; i < numsSize; ++i) {        tempNums[i] = nums[i];    }    qsort(tempNums, numsSize, sizeof(int), comp);    int head = 0;    int tail = numsSize - 1;    for (i = 0; i < numsSize; ++i) {        if (tempNums[head] + tempNums[tail] < target) {            ++head;        }        else if (tempNums[head] + tempNums[tail] > target){            --tail;        }        else {            for (i = 0; i < numsSize; ++i) {                if (tempNums[head] == nums[i]) {                    head = i;                    break;                }            }            for (i = numsSize - 1; i >= 0; --i) {                if (tempNums[tail] == nums[i]) {                    tail = i;                    break;                }            }            result[0] = head;            result[1] = tail;            return result;        }    }    return result;}int main(void){    int nums[] = {0, 4, 3, 0};    size_t numsSize = sizeof(nums)/sizeof(int);    int* result = twoSum(nums, numsSize, 0);    int i;    for (i = 0; i < 2; ++i)        printf("%d\n", result[i]);    free(result);    return 0;}

C++:用哈希,耗时19ms

#include <iostream>#include <vector>#include <map>using namespace std;vector<int> twoSum(vector<int>& nums, int target) {    vector<int> result;    map<int, int> hash;    for (size_t i = 0; i < nums.size(); ++i) {        map<int, int>::iterator it_find;        it_find = hash.find(nums.at(i));        if (it_find != hash.end()) {            result.push_back(it_find->second);            result.push_back(i);            return result;        hash.insert({target - nums.at(i), i});    }    return result;}int main(){    vector<int> nums = {2, 7, 11, 15};    vector<int> result = twoSum(nums, 9);    for (auto num : result)        cout << num << endl;    return 0;}

Java:用哈希,耗时6ms

import java.util.HashMap;public class TwoSum {    public static int[] twoSum(int[] nums, int target) {        int result[] = new int[2];        HashMap<Integer, Integer> hash = new HashMap<>();        for (int i = 0; i < nums.length; i++) {            if (hash.containsKey(nums[i])) {                result[0] = hash.get(nums[i]);                result[1] = i;                return result;            }            hash.put(target - nums[i], i);        }        return result;       }    public static void main(String[] args) {        int[] nums = {2, 7, 11, 15};        int[] reslut = twoSum(nums, 9);        for (int num : reslut) {            System.out.println(num);        }    }}

Python:用哈希,耗时45ms

#!/usr/bin/pythonclass Solution(object):    def twoSum(self, nums, target):        """        :type nums: List[int]        :type target: int        :rtype: List[int]        """        dict1 = {}        for i, value in  enumerate(nums):            if dict1.has_key(value):                return [dict1.get(value), i]            dict1[target - value] = i        return Nonenums = [2, 7, 11, 15]result = Solution().twoSum(nums, 9)print result
0 0