leetcode之路(两数之和)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值