您的位置:首页 > 其它

LeetCode 1_Two Sum

2015-07-01 16:10 309 查看
这是leetcode中的第一题,题目并不是很难,但对于我这个算法小白来说却也够了。废话不多说了,直接上题

原题:

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

题目的意思大概是给定一个整数数组,和一个目标和,要求从数组中找出两个数,使他们的和为目标和,记录这两个数的下标。

自己编的代码:

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> tempVec;
int index1=1;//记录下标
bool flag=false;//标识是否找到
for(vector<int>::iterator iter1=nums.begin();
iter1!=nums.end()&&flag==false;++iter1,++index1){
int index2=index1+1;if(*iter1>=target) continue;
for(vector<int>::iterator iter2=iter1+1;
iter2!=nums.end();++iter2,++index2){
if(*iter2>=target) continue;
if((*iter1+*iter2)==target){
tempVec.push_back(index1);
tempVec.push_back(index2);
flag=true;//找到了
}
}
}
return tempVec;
}
};
这个就不多解释了,相信大家都能看懂,程序的评判结果为运行超时,然后又找了一个大神的代码,代码用C++实现用时8ms,在排名中比较靠前因此被拿来学习(PS:谢谢leetcode上的大神 bobyaoswager提供的代码)。当然还有更快的实现方法,但这里主要是讲明概念,所以没有必要去找一个特定的最快解法

大神代码:

int compare(const void* a,const void* b)
{
return *(int*)a - *(int*)b;//返回*a-*b
}
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
vector<int>index;
int len = nums.size();//数组大小
int *temp = new int[len];
for(int i = 0; i < len; i++)
temp[i] = nums[i];//把数据复制到数组
qsort(temp,len,sizeof(int),compare);//快排
int left = 0;
int right = len - 1;
while(left < right)
{
if((temp[left] + temp[right]) > target)
right--;
else if((temp[left] + temp[right]) < target)
left++;
else
break;
}
for(int i = 0; i < len; i++)
{
if(nums[i] == temp[left] || nums[i] == temp[right])
index.push_back(i + 1);
}
delete[] temp;
return index;
}
};
看完这个结果我是挺诧异的,这数据倒来倒去的不浪费时间吗?怎么会这么快呢?由于本人不是计算机专业出身,所以只能去恶补了一下时间复杂度这个概念。通过简单的了解,学到了如下知识:

我的实现方法是最简单暴力的,通过一个一个去试的方法求解,虽然很容易理解,但时间复杂度为O(n2),这种算法会随着数据量的增加快速增加。而下面利用了快速排序的方法,首先对数据排序然后利用几个历遍便完成了算法设计。虽然看起来数据被历遍很多次,但每次历遍的复杂度只有n,而最关键的算法是快排,其复杂度为O(nlogn)。所以算法的整体复杂度为O(nlogn),这是比O(n2)快一个等级的,所以是比较理想的解题方法。

最后,抛开这些原理性的分析,我们可以看到两种算法最关键区别在于对数据的历遍次数不同。我写的代码是先确定一个数,然后历遍所有,再确定下一个,在然后再历遍所有,在这过程中会有很多次“重复的”历遍过程。而下面的算法把主要精力用在了排序上,而搜索过程只用来一次历遍。而关键在于对排序算法的选择,如果排序用冒泡或者选择这种复杂度为O(n2)的算法,那可以肯定下面算法的时间复杂度会变为O(n2)。可见,算法致胜的关键在于用快速排序的思想代替了选择排序的思想(我的算法实质是选择排序的思想,即n次历遍n个数据)。这启示我们以后再针对n次历遍n个数据这种情况时要小心行事,这通常不是一个好的思路。另外这也启示我们对时间复杂度的重视,要想更好的控制时间复杂度,应该对问题本身复杂度以及各种复杂度的推导有一个全面认识。这也是以后自己学习的一个方向。

时间有限,一些措辞就不讲究了,各位看懂就好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: