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%的提交,可见其算法的高效性。