您的位置:首页 > 其它

【LeetCode】Two Sum

2014-03-31 16:51 239 查看

参考:

题目描述:

http://oj.leetcode.com/problems/two-sum/


Two Sum

 

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

题目分析

题目大意:给出一个数组,及一个目标数,找到两个数之和等于目标数字。

函数需要返回相加等于目标数字的那两个数字在原数组中的索引。并且,要求index1<index2。index1是指在数据中从1开始算的索引。也就是说数据从1开始算下标而不是0

你可以假设一定存在一对数字。(就是说本题不用考虑不存在解的情况)

思路一:

使用map,构建一个<int,int>(<key,val>)的映射,其中key就是数组中的数字,而val表示该数字在数组中的索引值(从1计)

开始时所有map为空,遍历数据,逐个添加。mp[numbers[i]] = i+1;

添加之前判断map中是否已经有target-numbers[i]这个元素。if(mp.count(target-numbers[i]) != 0)

如果没有,就把这个结点添加到map,否则输出结点。两个索引值,一个是当前索引i+1,一个是(target-numbers[i])的val。

思路二

把数组进行排序,然后首尾各定义一个指针head,tail,
如果target>(num[head]+num[tail]) tail--;
如果target<(num[head]+num[tail]) head++;
有一个比较麻烦的地方就是要建立一个结点到索引的映射。因为排序过后原来的索引变了

类似题目:

阿里巴巴集团 2011届实习生招聘 技术笔试卷——公共题 第4题

4.参加百年阿里培训的n位同学结伴去西湖旁边为游人指路,两人一组,他们打算先让体重之和恰好为102公斤的同学一组,请给出一个算法找到这样的组合,或者确定他们中不存在这样的组合,其中最优的算法时间复杂度为?(假设体重均为整数) (     )

A:O(log(n))     B:O(n)      C:O(n log(n))    D:O(n^2)

总结:

这个对hash的考察

代码

/*
编译环境CFree 5.0
博客地址:http://blog.csdn.net/Snowwolf_Yang
*/
#include
#include
#include
using namespace std;

/*
思路做一个从map,开始时val都是0
从头开始遍历数据
key就是已经扫描过的整数,val是被扫描过的整数的index+1(因为输出要求数据从1开始)
复杂度为O(n)
*/
#if 1//map法
class Solution {
public:
vector twoSum(vector &numbers, int target) {
map mp;
vector out;
int i = 0, size = numbers.size();
for(i = 0;i twoSum(vector &numbers, int target) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector result;
vector array;
for (int i = 0; i < numbers.size(); i++)
{
Node temp;
temp.num = numbers[i];
temp.pos = i;
array.push_back(temp);
}

sort(array.begin(), array.end(), cmp);
for (int i = 0, j = array.size() - 1; i != j;)
{
int sum = array[i].num + array[j].num;
if (sum == target)
{
if (array[i].pos < array[j].pos)
{
result.push_back(array[i].pos + 1);
result.push_back(array[j].pos + 1);
} else
{
result.push_back(array[j].pos + 1);
result.push_back(array[i].pos + 1);
}
break;
} else if (sum < target)
{
i++;
} else if (sum > target)
{
j--;
}
}
return result;
}
};
#elif 1
class Solution {
public:
struct Node
{
int num, idx;
Node(int _num = 0, int _idx = 0):num(_num),idx(_idx){}
bool operator < (const Node& orh) const
{
if(num == orh.num)
return idx < orh.idx;
else return num < orh.num;
}
};
vector twoSum(vector &numbers, int target) {
// Start typing your C/C++ solution below
// DO NOT write int main() function

//step 0. get an arry record the num and index of every element
//step 1. sort the array and then
//step 2. enumerate every element numbers[i] in the array
//step 3. using binary search to find if there is an element equal to target-numbers[i]
//Time complexity Analysis: O(nlgn)

vector nodes(numbers.size());//step 0
for(int i = 0; i < numbers.size(); ++i)
nodes[i] = Node(numbers[i], i);

sort(nodes.begin(), nodes.end());//step 1
for(int i = 0; i < nodes.size(); ++i)//step 2
{
int v2 = target-nodes[i].num;
//step 3
int l = min(i+1, (int)nodes.size()-1);
int r = nodes.size()-1;
while(l <= r)
{
int mid = (l+r)/2;
if(nodes[mid].num > v2)
r = mid-1;
else if(nodes[mid].num == v2)
{
vector twoSum(2);
twoSum[0] = min(nodes[i].idx+1, nodes[mid].idx+1); twoSum[1] = max(nodes[i].idx+1, nodes[mid].idx+1);
return twoSum;
}
else l = mid+1;
}
}
}
};
#elif 1//暴力穷举 ----超时,过不去
class Solution {
public:
vector twoSum(vector &numbers, int target)
{
vectoroutput;
int i,j;
for(i=0;ii;j--)
{
if(numbers[i]+numbers[j]==target)
{
output.push_back(i+1);
output.push_back(j+1);
return output;
}
}
}
return output;
}
};
#endif

void test0()
{
int arr[] = {0,1,2,3,4,5,6,7,8,9};
vector numbers (arr, arr + sizeof(arr) / sizeof(int) );
Solution so;
vector out = so.twoSum(numbers, 7);
if(out.size() >= 2 && arr[out[0]-1] + arr[out[1]-1] == 7 && out[0] < out[1])
{
printf("arr[%d] = %d, arr[%d] = %d\n",out[0]-1,arr[out[0]-1],out[1]-1,arr[out[1]-1]);
printf("------------------------passed\n");
}
else
{
printf("arr[%d] = %d, arr[%d] = %d\n",out[0]-1,arr[out[0]-1],out[1]-1,arr[out[1]-1]);
printf("------------------------failed\n");
}
}
void test1()
{
int arr[] = {3,2,4};
vector numbers (arr, arr + sizeof(arr) / sizeof(int) );
Solution so;
vector out = so.twoSum(numbers, 6);
if(out.size() == 2 && arr[out[0]-1] + arr[out[1]-1] == 6 && out[0] < out[1])
{
printf("arr[%d] = %d, arr[%d] = %d\n",out[0]-1,arr[out[0]-1],out[1]-1,arr[out[1]-1]);
printf("------------------------passed\n");
}
else
{
printf("arr[%d] = %d, arr[%d] = %d\n",out[0]-1,arr[out[0]-1],out[1]-1,arr[out[1]-1]);
printf("------------------------failed\n");
}
}
int main()
{
test0();
test1();

return 0;
}



推荐学习C++的资料

C++标准函数库

http://download.csdn.net/detail/chinasnowwolf/7108919

在线C++API查询

http://www.cplusplus.com/
map使用方法

http://www.cplusplus.com/reference/map/map/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 两个数和