【LeetCode】167. Two Sum II
阿新 • • 發佈:2019-02-03
本題是亞馬遜的面試題。
題目描述:
一、第一種方法-暴力解法
當我們沒有頭緒,想不到更好的方法的時候,我們不妨用比較笨的方法來求解。
使用雙重迴圈:
for(int i = 0 ; i < numbers.size() ; i ++) for(int j = i+1 ; j < numbers.size() ; j ++) if(numbers[i] + numbers[j] == target){ int res[2] = {i+1, j+1}; return vector<int>(res, res+2); }
完整實現原始碼:
#include <iostream> #include <vector> #include <cassert> using namespace std; // 暴力列舉法 // 時間複雜度: O(n^2) // 空間複雜度: O(1) class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { assert(numbers.size() >= 2); // assert(isSorted(numbers)); for(int i = 0 ; i < numbers.size() ; i ++) for(int j = i+1 ; j < numbers.size() ; j ++) if(numbers[i] + numbers[j] == target){ int res[2] = {i+1, j+1}; return vector<int>(res, res+2); } throw invalid_argument("the input has no solution"); } private: bool isSorted(const vector<int>& numbers){ for(int i = 1 ; i < numbers.size() ; i ++) if(numbers[i] < numbers[i-1]) return false; return true; } }; int main() { int nums[] = {2, 7, 11, 15}; vector<int> vec(nums, nums + sizeof(nums) / sizeof(int)); int target = 9; vector<int> res = Solution().twoSum(vec, target); for(int i = 0 ; i < res.size() ; i ++) cout << res[i] << " "; cout << endl; return 0; }
二、第二種方法- 二分查詢法
使用二分查詢法是比較容易想到的一個方法,只需使用二分查詢法找到target - numbers[i] 即可:
for(int i = 0 ; i < numbers.size() - 1 ; i ++){ int j = binarySearch(numbers, i+1, numbers.size()-1, target - numbers[i]); if(j != -1){ int res[2] = {i+1, j+1}; return vector<int>(res, res+2); } }
當i = 0時:
使用二分查詢法找到num[j] :
int binarySearch(const vector<int> &nums, int l, int r, int target){
assert(l >= 0 && l < nums.size());
assert(r >= 0 && r < nums.size());
while(l <= r){
int mid = l + (r - l)/2;
if(nums[mid] == target)
return mid;
if(target > nums[mid])
l = mid + 1;
else
r = mid - 1;
}
return -1;
}
完成實現原始碼:
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
// 二分搜尋法
// 時間複雜度: O(nlogn)
// 空間複雜度: O(1)
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
assert(numbers.size() >= 2);
// assert(isSorted(numbers));
for(int i = 0 ; i < numbers.size() - 1 ; i ++){
int j = binarySearch(numbers, i+1, numbers.size()-1, target - numbers[i]);
if(j != -1){
int res[2] = {i+1, j+1};
return vector<int>(res, res+2);
}
}
throw invalid_argument("the input has no solution");
}
private:
int binarySearch(const vector<int> &nums, int l, int r, int target){
assert(l >= 0 && l < nums.size());
assert(r >= 0 && r < nums.size());
while(l <= r){
int mid = l + (r - l)/2;
if(nums[mid] == target)
return mid;
if(target > nums[mid])
l = mid + 1;
else
r = mid - 1;
}
return -1;
}
bool isSorted(const vector<int>& numbers){
for(int i = 1 ; i < numbers.size() ; i ++)
if(numbers[i] < numbers[i-1])
return false;
return true;
}
};
int main() {
int nums[] = {2, 7, 11, 15};
vector<int> vec(nums, nums + sizeof(nums) / sizeof(int));
int target = 9;
vector<int> res = Solution().twoSum(vec, target);
for(int i = 0 ; i < res.size() ; i ++)
cout << res[i] << " ";
cout << endl;
return 0;
}
三、’第三種方法-對撞指標
對於陣列numbers[ ],
取 i = 0, j = numbers.size() - 1; 即
①if (numbers[ i ] + numbers[ j ] < target)
i++;
②if (numbers[ i ] + numbers[ j ] > target)
j++;
③if (numbers[ i ] + numbers[ j ] > target)
完成查詢。
完成原始碼:
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
// 對撞指標
// 時間複雜度: O(n)
// 空間複雜度: O(1)
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
assert(numbers.size() >= 2);
// assert(isSorted(numbers));
int l = 0, r = numbers.size() - 1;
while(l < r){
if(numbers[l] + numbers[r] == target){
int res[2] = {l+1, r+1};
return vector<int>(res, res+2);
}
else if(numbers[l] + numbers[r] < target)
l ++;
else // numbers[l] + numbers[r] > target
r --;
}
throw invalid_argument("the input has no solution");
}
private:
bool isSorted(const vector<int>& numbers){
for(int i = 1 ; i < numbers.size() ; i ++)
if(numbers[i] < numbers[i-1])
return false;
return true;
}
};
int main() {
int nums[] = {2, 7, 11, 15};
vector<int> vec(nums, nums + sizeof(nums) / sizeof(int));
int target = 9;
vector<int> res = Solution().twoSum(vec, target);
for(int i = 0 ; i < res.size() ; i ++)
cout << res[i] << " ";
cout << endl;
return 0;
}
參考資料: