一、題目
原題鏈接:https://leetcode.com/problems/two-sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
題目翻譯:
給定一個整型數組,找出能相加起來等於一個特定目標數字的兩個數。
函數 twoSum 返回這兩個相加起來等於目標值的數字的索引,且 index1 必須小於 index2。 請記住你返回的答案(包括 index1 和 index2)都不是從 0 開始的。
你可以假定每個輸入都有且僅有一個解決方案。
輸入: numbers={2, 7, 11, 15}, target=9
輸出: index1=1, index2=2
二、解題方案
方案1 - 暴力法
思路:
通過雙重循環(內層循環要從外層循環下標加一開始,避免遍歷到兩個相同的元素)遍歷數組中所有元素僅僅兩兩組合,當出現符合的和時返回兩個元素的下標。
代碼實現:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
for(int i = 0 ; i < nums.size() ; ++i)
{
for(int j = i+1 ; j<nums.size() ; ++j)
{
if(nums[i]+nums[j] == target)
{
result.push_back(i);
result.push_back(j);
return result;
}
}
}
}
};
算法時間複雜度爲O(N^2),空間複雜度爲O(1)。而且在LeetCode上提交代碼會提示Time Limit Exceeded,時間超限。
方案2 - Hash
思路:
建立hashmap,去查找餘數是否存在。等式轉換一下,我們可以知道,a=target-b。所以我們要做的事情可以翻譯爲,找到一個數a,滿足a與target-a都在數組之中。
代碼實現:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
for(int i = 0 ; i < nums.size() ; ++i)
{
for(int j = i+1 ; j<nums.size() ; ++j)
{
if(nums[i]+nums[j] == target)
{
result.push_back(i);
result.push_back(j);
return result;
}
}
}
}
};
哈希表查找的時間複雜度是O(1),相比方案一,我們藉助哈希表查找可以將時間複雜度降低到O(N)。算法空間複雜度O(N)。
方案3 - 雙指針掃描
思路:
首先將數組進行排序。排序後將雙指針指向頭部與尾部元素,進行迭代。如果雙指針指向元素之和大於目標和,則將尾部指針向前移一位,反之則將頭部指針向後移一位,直到雙指針指向元素之和等於目標和,記錄這兩個元素的值,然後再遍歷一遍舊數組,找出這兩個元素的下標。
class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
vector<int> result;
int low=0, high = numbers.size()-1;
while (low < high){
if (numbers[low] + numbers[high] == target){
result.push_back(low+1);
result.push_back(high+1);
return result;
}else{
numbers[low] + numbers[high] > target ? high-- : low++;
}
}
return result;
}
};