首页 > 代码库 > LeetCode_1 TwoSum

LeetCode_1 TwoSum

看书尽管有必要,可是光看书大家斗志到是无用的,可是没办法。科研项目和互联网没关,仅仅能找点题目来刷了!

不多说。開始!

LeetCode_1   TwoSum

题目说明:

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

翻译:给定一个整数数组,找出当中两个数满足相加等于你指定的目标数字。

要求:这个函数twoSum必需要返回可以相加等于目标数字的两个数的索引,且index1必需要小于index2。

请注意一点,你返回的结果(包含index1和index2)都不是基于0開始的。可以如果每个输入肯定仅仅有一个结果

拿到题先省清楚,一看到这题,肯定想到的是暴力法,可是不要接下去这样做,显然题目不会要求这么去做的,毕竟暴力法时间复杂度有点让人忍受不了。O(n^2)!

既然暴力法不行。非常easy想到的方法有:

1、先排序。再两边往中间扫描。

2、哈希map(没去做)

本文主要是第一个方法。说下哈希表的思想(没实现):

先贴代码(通过验证):

<span style="font-size:18px;">#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void QuickSort(vector<int> & nums, int first, int last)
{
	// 高速排序 O(nlog2(n))
	int tmp;
	int i =first, j = last;
	vector<int>::iterator iter = nums.begin();
	if (first < last)
	{
		tmp = *(iter + first);
		while (i != j)
		{
			while (j > i && (*(iter + j) >= tmp))
				j--;
			*(iter + i) = *(iter + j);

			while (j > i && ( *(iter + i) <= tmp ) )
				i++;
			*(iter + j) = *(iter + i);
		}
		*(iter + i) = tmp;
		QuickSort(nums, first, i - 1);
		QuickSort(nums, i + 1, last);
	}
}

bool cmp(int a, int b)
{
	return a < b;
}

class Solution
{
public:
	vector<int> twoSum(vector<int>& nums, int target) 
	{
		vector<int> Array;
		for(vector<int>::iterator iter = nums.begin();iter != nums.end(); iter++)
			Array.push_back(*iter);

		sort(nums.begin(), nums.end(), cmp);
		//QuickSort(nums, 0, nums.size() - 1); 
        
		vector<int> result;
		for (int i = 0, j = nums.size() - 1; i != j;)
		{
			int sum = *(nums.begin() + i) + *(nums.begin() + j);
			if ( sum == target )
			{
				int num1 = *(nums.begin() + i);
				int num2 = *(nums.begin() + j);
				vector<int> result;
				int tmp1 = 0, tmp2 = 0, k = 1;
				for(vector<int>::iterator iter = Array.begin(); iter != Array.end(); iter++, k++)
				{
					if(*iter == num1 || *iter == num2)
						result.push_back(k);
					if (result.size() == 2)
					    return result;
				}
			}
			else if(sum < target)
				i++;
			else if(sum > target)
				j--;
		} 	
	}
};</span>

首先,本来我自己写了个排序算法(高速排序),时间复杂度为O(nlog2n),可是在leetcode中上传后说超时,囧,后来用了自带的sort(algorithm头文件里),才没有出现超时的问题。

sort函数能够參考:http://blog.csdn.net/jiangyaoyan/article/details/5416983

我这里首先将数据背了个份,由于排序的时候肯定会破坏原来的顺序(也能够使用结构体,保存数据及其相应的位置,最后依照结构体的数据排序,这样即使原先的位置不一样了,结构体中也记录了原先元素相应的位置),排好序后。在两端设置指针,指针往中间靠拢就可以。

假设全部的数据都是正的。还能够排好序后先从后往前扫,把大于target的元素直接排除,原因就不用我说了吧!


哈希表

至于哈希map是什么大家都不陌生,其拥有非常好的搜索性能,所以要使用哈希map就要将问题转化到搜索上来。首先将元素及其下标作为<key,value>存入到hash-map中去,之后可取一个元素(如果为v1),则在hash-map中搜索(target - v1),因为哈希表的平均搜索次数为O(1)。所以整个下来时间复杂度为O(n),比上面的方法好。实现能够參考:http://segmentfault.com/a/1190000002986095?_ea=258426




LeetCode_1 TwoSum