題目描述:給定一個整數數組,返回其中兩個數的下標,使它們的和等于指定的目標值。如:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
分析:兩重循環直接查找一定超時。用哈希表存儲每個數的下標,從前往后遍歷查找每個數的差值是否存在,復雜度O(n)。還可以先排序,然后左右夾逼,總復雜度O(nlgn),但排序后下標順序就打亂了,故不可行,若只返回兩個數字則可行。
哈希方法一:需遍歷數組兩次,第一次將值和對應下標存入哈希表,第二次查找。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> map; //數值,對應下標
vector<int> v;
for (int i = 0; i < nums.size(); i ++)
map[nums[i]] = i;
for (int i = 0; i < nums.size(); i ++)
{
int gap = target - nums[i];
if (map.find(gap) != map.end() && map[gap] != i) //找到差值且不是nums[i]本身
{
v.push_back(i);
v.push_back(map[gap]);
break;
}
}
return v;
}
};
哈希方法二:只遍歷數組一次,存哈希表的同時查找,第一次沒找到,到其差值時就可返回。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> map;
vector<int> v;
for (int i = 0; i < nums.size(); i ++)
{
int gap = target - nums[i];
if ( map.count(gap) ) //找到其差值
{
v.push_back(i);
v.push_back(map[gap]);
break;
}
if(map.count(nums[i]) != 1) //字面是沒有記錄過或者出現超過一次,此處是沒有出現過
{
map[nums[i]] = i;
}
}
return v;
}
};
若返回和為定值的兩數字時的排序法:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int i = 0, j = nums.size() - 1;
vector<int> v;
while (i < j)
{
if (nums[i] + nums[j] == target)
{
v.push_back(nums[i]);
v.push_back(nums[j]);
break;
}
else if (nums[i] + nums[j] < target)
{
i ++;
}
else
j --;
}
return v;
}
};