【c++】leetcode twosum 两数之和

【c++】leetcode twosum 两数之和

  • 题目
    • 分析
    • 暴力求解
    • 进阶求解
      • 哈希表求解法初级版
      • 哈希求解法升级版

题目

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

分析

这道题乍一看,一点也不难,不就是遍历两遍就好了,但是坑有两个:

  1. 不能重复利用数组中同样的元素
    刚开始写你可能不会注意,遍历起来i=0, j=0就会踩到这样的坑,j = i 也会!
  2. 每种输入只对应一个答案
    你也不能 j = i ,这样你就重复的用了两遍了元素,j = i+1就错开了

暴力求解

class Solution {
public:
    vector<int> result={};
    vector<int> twoSum(vector<int>& nums, int target) {
        for (int i=0;i< nums.size();i++)
            for (int j = i+1; j < nums.size(); j++)
            {
                if (nums[i]+nums[j]==target)
                {
                    result.push_back(i);
                    result.push_back(j);
                    return result;
                }
            }
        return result;
    }
};

进阶求解

不要以为这题就完了!还有更厉害的求解方法
如果要用到查找,第一时间应该想到哈希!O(1)!完美

哈希表求解法初级版

开动你的小脑筋,怎么用哈希求解!
啊哈!如果查找的键值正好等于 目标值-当前遍历的数值 那不一次就查到了!
所以,一开始遍历一遍数据表,把数据表的值存成哈希的key,然后value存成该值的索引index。再重新遍历一遍数据表,根据每次遇到的数值可以求到目标值与之的差值,然后用哈希瞬间查找到这个差值,也就是遍历一遍的复杂度O(n)!
所以解法如下

class Solution {
public:
	\\我喜欢在一开始全部申请完变量哇
    vector<int> result={};
    map<int, int> testmp;
    int i, temp;
    
    vector<int> twoSum(vector<int>& nums, int target) {
        \\遍历一遍原始的list,存进哈希表
        \\key是当前的index的值,value是index
        for(i = 0; i<nums.size(); i++)
            testmp.insert({nums[i],i});
        
        for(i= 0; i< nums.size(); i++)
            {
            	\\为了节约每次计算的时间
                temp = target-nums[i];
                \\如果键值里面有这个数的话直接输出了,因为只有一个解!
                \\这里注意哇,不能重复使用一个数,所以要判断是不是等于当前index
                if (testmp.count(temp)!=0 && testmp[temp]!=i)
                {
                        result.push_back(i);
                        result.push_back(testmp[temp]);
                        return result;
                }
            }
        return result;   
    }      
};

这个有两次循环,虽然是O(n)的时间,但是其实是2n的时间,有没有更好的方法呢!!答案当然是有的!不然我也不会打这段废话啦!!

哈希求解法升级版

是不是觉得上面哪里可以节约掉!开动你的小脑筋!!
对!!就是再一次遍历的那里!
根本不用存一遍进去再查找的,可以边存边查找鸭!!为什么可以边存边查找呢!你胡说!!你就不怕查找的那个元素下一次就不在了就不能返回了吗!!!
嘿,我就是不怕,原因是!!第一次出现的差值如果在前面,就会立马返回这个index,而如果在后面的话这次不返回,但是下次目标与这个本来要返回的值的差值就是前面这个数鸭 也就是总要返回的两个数,有个必定出现在另外一个之前啊, 怎么有点爱情哲学的感觉???
举个例子
[2,1,3,4]
5
第一次入哈希表[{2,0}] 5-2 = 3无事发生,找不到3现在!如果是原来已经插好的表的话此时应该返回3的索引2了!但是没关系!!我们现在拥有了2!!!
第二次入哈希表[{2,0},{1,1}] 无事发生 5 - 1 = 4 没有出现
第三次入哈希表[{2,0},{1,1},{3,2}] 酱酱酱酱!!5-3 =2!有了有了!!返回
来看看代码,就把刚刚的合并一下,其实还可以优化一些细节,比如如果插入是在后面的话就不用判断当前的index是否为i了,可以少插入一次

class Solution {
public:
    vector<int> result={};
    map<int, int> testmp;
    int i, temp;
    
    vector<int> twoSum(vector<int>& nums, int target) {
        
        for(i = 0; i<nums.size(); i++)
        {
            testmp.insert({nums[i],i});
            temp = target-nums[i];
            if (testmp.count(temp)!=0 && testmp[temp]!=i)
            {
                    result.push_back(i);
                    result.push_back(testmp[temp]);
                    return result;
            }
        }
        return result;   
    }
};

这个能一次循环的原因就在于有一个必出现在另一个之前,如果是其他的还要具体分析哦!!不是每次哈希查找都能合并的!!(我觉得,嘻嘻)

有问题留言哇

你可能感兴趣的:(【c++学习】)