1. 两数之和
给定一个整数数列,找出其中和为特定值的那两个数。
你可以假设每个输入都只会有一种答案,同样的元素不能被重用。
示例:给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
ps:第一种方法可以直接暴力解答。时间复杂度O(n^2)。
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
vector<int> ans;
int size = nums.size();
for(int i = 0; i < size; i++)
{
for(int j = i + 1; j < size; j++)
{
if(nums[i] + nums[j] == target)
{
ans.push_back(i);
ans.push_back(j);
return ans;
}
}
}
}
};
第二种方法可以用散列表(hash)来做。依次循环该数组,如果要加入的元素与表中的某个元素的键值的和
等于target, 则为加入答案中,否则将其加入表中。时间复杂度O(nlogn)。
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
vector<int> ans;
map<int, int> hashT;
int size = nums.size();
map<int, int> :: iterator it;
for(int i = 0; i < size; i++)
{
if((it = hashT.find(target - nums[i])) != hashT.end())
{
ans.push_back(it -> second);
ans.push_back(i);
return ans;
}
else
hashT.insert(map<int,int>::value_type(nums[i], i));
}
}
};
第三种方法可以用双指针来解决。先进行稳定排序,当头指针和尾指针的元素之和大于target,尾指针-1(因为头指针+1的结果肯定大于target),同理当头指针和尾指针的元素之和小于target,头指针+1。时间复杂度O(nlogn)。注意对于这道题要用结构体先保存元素的值和下标。
struct Num
{
int value;
int index;
};
bool cmp(const Num &n1, const Num &n2)
{
return n1.value < n2.value;
}
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
int top = 0;
int size = nums.size();
int tail = size - 1;
Num num[size];
for(int i = 0; i < size; i++)
{
num[i].value = nums[i];
num[i].index = i;
}
stable_sort(num, num + size, cmp);
vector<int>ans;
while(top < tail)
{
if(num[top].value + num[tail].value == target)
{
ans.push_back(num[top].index);
ans.push_back(num[tail].index);
return ans;
}
else if(num[top].value + num[tail].value > target)
--tail;
else ++top;
}
return ans;
}
};