别看了,LeetCode第一题会了吗(两数之和)

写在前面的话

相信大家对于这道题已经不陌生的了,但是往往会有人在这回忆过去:

“有人翱游世界,有人夜里看海,有人leetcode第一题做不出来……”

你一定不会,要不你怎么会来到这 ^-^

题目描述

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

解析

相信大家对于第一种暴力解法已经“融会贯通”了,因为……em是吧,就不解释了。

那么可能对于题目的要求:如何用小于 O(N^2) 时间复杂度的条件下完成?

一个大致的思路可能是用哈希?

可能对于搜索,更快的能想到是哈希,因为它的搜索是O(1)。那么如何用哈希是一个问题?

那么哈希要搜索什么?(what

对,暴力解法中,困扰我们的问题是什么,就是寻找 target - nums[i] 这个值的过程,用了O(N)的复杂度。 

所以,将要搜索的值放入哈希表,就解决了这个问题。

那么,怎么放(how

a. 直接扫描存入。扫描每个值存入哈希表。(有问题吗?)

b. 遍历数组,对于当前元素 nums[i],在哈希表中寻找 target-nums[i] 是否存在。如果不存在,说明和nums[i] 匹配的值 target-nums[i] 并不存在于哈希表中。再将该值存入哈希表。

对于这两种方式。第一种显然是不可能的,因为假如我有两个相等的数存入,那么你用哪种哈希结构能存储?因为这里你还需要考虑到返回的结果是 “下标” ,所以你存入的方式一定是这样的一个键值对:

                                                   pair<nums[i] , i>

也就是,当前元素和元素的下标。那么如果有重复元素,就产生冲突了,因为这里的second存储的不是常规的计数值,而是当前元素的下标。

所以我们采用第二种实现方式,就可以理解为什么要这么遍历存储了。

当解决了存储问题之后,这个问题的思路就有了。

那么解决了target-nums[i] 这个值的查找情况的时候,这个题目也就解决了。

代码实现

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> mp;
        for(int i=0;i<nums.size();i++)
        {
            auto it = mp.find(target-nums[i]);
            if( it == mp.end())
                mp[nums[i]]=i;
            else
                return {i,it->second};
        }
        return {};
    }
};

Important

几个细节点,如果忽略细节,那么你看完了跟你将这个题目结果背了一遍,没有任何区别。

1.存储的是什么?为什么这么存储?能不能采用其他方式存储?

2.找对应值的时候,我们的思路是什么?

3.返回的值是什么?怎么返回呢?

相信如果你对于以上三个问题有了理解,那么下回你就不用一次又一次 

又回到最初的起点,记忆中你超时的脸~

好的,如果你有不一样的思路请多多指教奥~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值