问题
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
代码
//
// toSum.cpp
// Test
//
// Created by mac on 5/18/14.
// Copyright (c) 2014 mac. All rights reserved.
//
#include "toSum.h"
#include <algorithm>
#include <iterator>
#include <vector>
using namespace std;
struct node{
int index;
int value;
};
bool compile(const struct node &a , const struct node &b)
{
return a.value < b.value;
}
class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
/* init a vector */
vector<struct node> temp(numbers.size());
struct node n;
for (int i = 0 ; i < numbers.size() ; i ++) {
n.index = i+1; n.value = numbers[i];
temp[i] = n;
}
vector<int> resultv;
sort(temp.begin() , temp.end() , compile);
for (int i = 0 , j = temp.size()-1; i < j; ) {
if (temp[i].value + temp[j].value == target)
{
resultv.push_back(min(temp[i].index,temp[j].index));
resultv.push_back(max(temp[i].index,temp[j].index));
break;
}
else if(temp[i].value + temp[j].value < target)
{
i++;
}
else if(temp[i].value + temp[j].value > target)
{
j--;
}
}
return resultv;
}
};
其中主要熟悉STL 的 vector , sort 的用法掌握就行了。
分析:
1.两个for循环的数组来遍历I,J,相加是否有target答案,就可以算出答案了,这个就是穷举法,算法复杂度是O(N^2),显然并非最优。
2. 上面的做法,首先先排序,利用的是sort,内部实现是一个类《快速排序》的排序算法,所以时间复杂度为 O(nlogn),
排序完成之后,数组两头设置指针,并向中间紧逼,如果大于target,则左移大指针,如果小于target,则右移小指针。主要原理是:
1.如果两个值相加大于target,则右指针右移,只会更大,显然没有意义,此时应该保留左指针不变,移动右指针,往左移动,试图等于target.
2.如果两个值相加小于target,则需要右移动左指针,目的主要是试图加大target,这个时候有一个疑问了,其实也可以右移动右指针,可是这样做也毫无意义:因为右指针左移的目的是因为右指针加上了比此时做指针的所有左边的数(包括它本身),加起来还要大,基于大于target,所以才左移的,所以右移加上此时的左指针值,则只会更大,所以无意义。
因为以上第二步的时间复杂度威O(N)。
所以相加,忽略O(N),则总得时间复杂度是O(nlogn)。