LeetCode 001. Two Sum

来源:互联网 发布:淘宝个人工商营业执照 编辑:程序博客网 时间:2024/06/08 18:33

Two Sum

 

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

思路:

这个题目最简单的方法就是用两个for循环嵌套求和并和目标一一对比,但是我们结果是Time Limit Exceeded

网上很多人用的方法是排序,在排序前用个struct记录数值和下标。然后从排序好的数组两头分别开始求和。

例如以下代码(个人觉得以下代码写的非常nice!):

struct Node{    int val;    int index;    Node(){}    Node(int v, int idx):val(v), index(idx){}};bool compare(const Node &lhs, const Node &rhs){    return lhs.val < rhs.val;}class Solution {public:    vector<int> twoSum(vector<int> &numbers, int target) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        vector<Node> a;        for(int i = 0; i < numbers.size(); i++)            a.push_back(Node(numbers[i], i + 1));        sort(a.begin(), a.end(), compare);                int i = 0;        int j = numbers.size() - 1;        while(i < j)        {            int sum = a[i].val + a[j].val;            if (sum == target)            {                vector<int> ret;                int minIndex = min(a[i].index, a[j].index);                int maxIndex = max(a[i].index, a[j].index);                ret.push_back(minIndex);                ret.push_back(maxIndex);                return ret;            }            else if (sum < target)                i++;            else                j--;        }    }};

另外还推荐一种思路是用map来解决本题。

class Solution {public:    vector<int> twoSum(vector<int> &numbers, int target) {          unordered_map<int, int> mp;          vector<int> ans;          for(int i = 0; i < numbers.size(); i ++)          {              if(mp.count(target - numbers[i]))              {                 ans.push_back(mp[target - numbers[i]] + 1);                 ans.push_back(i + 1);                 break;             }             if(!mp.count(numbers[i])) mp[numbers[i]] = i;//这里是map的生成,由于一组和两个数一前一后有两种情况,这里按题目要求只取其中一种         }         return ans;    }}; 
但是我觉的既然题目中已经说明我们可以假设输出结果是唯一的,那么我们为什么要记录下标呢?

我们可以先将vector复制一份,对新复制的vector排序,然后直接找到这样的两个数之和等于目标数值,然后再去数组中找寻两个加数的下标。

class Solution {public:vector<int> twoSum(vector<int> &numbers, int target) {int i,j;vector<int>nums(numbers);vector<int>index(2,0);sort(nums.begin(),nums.end());//默认采用升序排序i = 0;j = nums.size()-1;while(i<j){if (nums[i]+nums[j]<target)i++;else if(nums[i]+nums[j]>target)j--;else if(nums[i]+nums[j]==target)break;}//一个从前往后找,一个从后往前找,避免两个数是同一个值,测试用例{0,4,5,0} target = 0int temp = 0;while(temp < nums.size()){if (numbers[temp]== nums[i]){index[0]=temp+1;break;}temp ++;}temp = nums.size()-1;while(temp >=0){if (numbers[temp]== nums[j]){index[1]=temp+1;break;}temp --;}//这一步检查是为了防止小的数在大的数后面,测试用例,16,2,3,4,5,7,8} target=20if(index[0]>index[1]){temp = index[0];index[0]=index[1];index[1]=temp;}return index;}};

测试代码:

#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){int target = 30;vector<int>nums;vector<int>index;nums.insert(nums.end(),0);nums.insert(nums.end(),4);nums.insert(nums.end(),71);nums.insert(nums.end(),15);nums.insert(nums.end(),3);nums.insert(nums.end(),9);nums.insert(nums.end(),17);nums.insert(nums.end(),13);nums.insert(nums.end(),25);nums.insert(nums.end(),1);nums.insert(nums.end(),33);nums.insert(nums.end(),0);for(int i=0;i<nums.size();i++){cout<<"nums["<<i<<"]="<<nums[i]<<endl;}Solution sol;index = sol.twoSum(nums,target);for(int i=0;i<index.size();i++)cout<<index[i]<<endl;return 0;}

runtime: 48ms



1 0
原创粉丝点击