首页 > 编程语言 > 详细

【LeetCode-数组】两数之和

时间:2020-04-06 12:06:03      阅读:58      评论:0      收藏:0      [点我收藏+]

题目描述

给定一个整数数组 nums?和一个目标值 target,请你在该数组中找出和为目标值的那?两个?整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

题目链接:https://leetcode-cn.com/problems/two-sum

思路1

遍历两遍数组,第一遍遍历时固定一个数字x,在第二遍遍历时寻找另一个数字target-x,要注意x和target-x的下标不能相同。代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> ans;
        if(nums.empty())
            return ans;

        for(int i=0; i<nums.size(); i++){
            int idx = hasAnotherNum(target-nums[i], nums, i);
            if(idx!=-1 && idx!=i){
                ans.push_back(i);
                ans.push_back(idx);
                return ans;
            }
        }
        return ans;
    }

    int hasAnotherNum(int num, vector<int> nums, int curNumIdx){
        for(int i=0; i<nums.size(); i++){
            if(i!=curNumIdx && nums[i]==num)
                return i;
        }
        return -1;
    }
};
  • 时间复杂度O(n^2)
    因为遍历每一个数字的时候,还需要遍历一遍(n次)去寻找另一个数字,共n个数字,所以时间复杂度为O(n^2).
  • 空间复杂度O(1)
    算法运行需要的辅助空间和输入规模无关,空间复杂度为O(1).

思路2

思路2是对思路1在时间复杂度上的优化。思路1比较慢的原因是,每次要用一个循环来查找元素。查找元素比较快的方法是哈希表,哈希表查找元素的时间复杂度为O(1),可以大大地降低查找耗时。这里使用c++的map来实现哈希表。代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> ans;
        if(nums.empty())
            return ans;

        map<int, int> hashTabel;
        for(int i=0; i<nums.size(); i++)
            hashTabel[nums[i]] = i;    // 建立哈希表
        
        for(int i=0; i<nums.size(); i++){
            int complement = target-nums[i];
            if(hashTabel.find(complement)!=hashTabel.end() && hashTabel[complement]!=i){
                ans.push_back(i);
                ans.push_back(hashTabel[complement]);
                return ans;
            }
        }
        return ans;
    }
};
  • 时间复杂度为O(n)
    两个并列的循环,时间复杂度为O(n).
  • 空间复杂度O(n)
    哈希表占用的空间随输入规模的上式线性增长,所以空间复杂度为O(n).

思路3

还可以对思路2进一步优化。思路二使用了两个并列的循环,其中第一个循环用来建立哈希表。其实,可以边判断边建立哈希表,也就是使用1个循环。代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> ans;
        if(nums.empty())
            return ans;

        map<int, int> hashTabel;

        for(int i=0; i<nums.size(); i++){
            if(hashTabel.find(target-nums[i])!=hashTabel.end()){
                ans.push_back(hashTabel[target-nums[i]]);   //先放hashTabel[target-nums[i]]
                ans.push_back(i);
                return ans;
            }
            hashTabel[nums[i]] = i;
        }
        return ans;
    }
};

需要注意的是,在ans中要先放hashTabel[target-nums[i]],后放i。因为hashTabel[target-nums[i]]更小。
时间复杂度和空间复杂度与思路2相同。

【LeetCode-数组】两数之和

原文:https://www.cnblogs.com/flix/p/12640983.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!