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

發佈了17 篇原創文章 · 獲贊 27 · 訪問量 2631
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章