leetcode之路(兩數之和)
題目:
給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和爲目標值的那 兩個 整數,並返回他們的數組下標。
你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個數組中同樣的元素。
示例:
給定 nums = [2, 7, 11, 15], target = 9
因爲 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
“實現一個功能如果需要10分鐘,思考的時間是7分鐘”
思考過程:
方法一:不需要太多思考的方法,竟然要在一個數組中找到兩個數的和爲target,我們只需要將nums中的數兩兩相加,總是可以找到我們想要的那兩個數,然後返回存有他們的下標的數組就好了。
該方法的關鍵代碼如下:
vector<int> twoSum(vector<int>& nums, int target){
vector<int> ret;
for(int i=0;i<nums.size()-1;i++){
for(int j=i+1;j<nums.size();j++){
if(nums[i]+nums[j]==target){
ret.push_back(i);
ret.push_back(j);
}
}
}
return ret;}
提交結果:
√ Accepted
√ 29/29 cases passed (548 ms)
√ Your runtime beats 7.33 % of cpp submissions
√ Your memory usage beats 89.25 % of cpp submissions (9.2 MB)
可見我們的方法是可行的,但是隻超過7.33%的提交?這也太低了吧。這個方法簡單,代碼也簡單,但是時間複雜度O(n^2)。
方法二:
題目中給的數組不是有序數組,假設是有序數組(這裏假設是遞增數組),我們只需要設兩個指針分別指向最大和最小的數(如圖),用這兩個數的值與target比較,若大了,則將j前移一位,若小了,則將i後移一位,就這樣兩數之和就會一步一步的接近target,時間比方法一省很多。but,又有新問題了,若是對nums進行排序,這些數所對應的下標也會發生改變。因此我們要使用結構體Node將數與原來的下標綁定在一起;然後將數組內的數全部轉化爲Node對象,並存入vector中,使用sort進行排序後,用前面提到的雙指針的方法找到兩個符合題意(data之和爲target)的Node並返回他們的index就可以了;
代碼如下:
/*
* @lc app=leetcode.cn id=1 lang=cpp
*
* [1] 兩數之和
*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
#include<vector>
struct Node{
int data;
int index;
};
class Solution {
public:
static bool comp(Node a,Node b){
return a.data<b.data;
}
vector<int> twoSum(vector<int>& nums, int target){
vector<int>ret;
vector<Node>Arrnode;
for(int i=0;i<nums.size();i++){
Node item;
item.data=nums[i];
item.index=i;
Arrnode.push_back(item);
}
sort(Arrnode.begin(),Arrnode.end(),comp); //排序
int start=0;
int end=Arrnode.size()-1;
while(start<end){
if(Arrnode[start].data+Arrnode[end].data==target){
if(Arrnode[start].index<Arrnode[end].index){
ret.push_back(Arrnode[start].index);
ret.push_back(Arrnode[end].index);
}
else{
ret.push_back(Arrnode[end].index);
ret.push_back(Arrnode[start].index);
}
return ret;
}
else if(Arrnode[start].data+Arrnode[end].data<target){
start++;
}
else {end--;}
}
return ret;}
};
提交結果:
√ Accepted
√ 29/29 cases passed (12 ms)
√ Your runtime beats 93.5 % of cpp submissions
√ Your memory usage beats 46.48 % of cpp submissions (9.7 MB)
雖然方法二,在思維和實現都比方法一要複雜一點,但是超過93.5%的提交,可見其算法的高效性。