首页 > 其他分享 >LeetCode-两数之和

LeetCode-两数之和

时间:2024-08-06 12:27:56浏览次数:4  
标签:target nums 复杂度 leq 哈希 mathcal LeetCode 两数

前言

这道题是Leetcode的第一题,也是经典题目之一,几乎所有刷题网站的第一题都是“两数之和”,只是Leetcode这道题不一样。
在这篇博客中,我们介绍了两种解法:

暴力算法 哈希表算法
\(\mathcal{O}(n^2)\) \(\mathcal{O}(n)\)

题目描述

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

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

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

示例1:

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

示例2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例2:

输入:nums = [3,3], target = 6
输出:[0,1]

提示

  • \(2 \leq nums.length \leq 10^4\)
  • \(-10^9 \leq nums[i] \leq 10^9\)
  • \(-10^9 \leq target \leq 10^9\)
  • 只会存在一个有效答案

题目分析

由于题目描述得比较清晰,所以不用过多分析。需要注意的是,题目已经说明每种输入只对应一个答案,说明我们不用考虑有多个答案的情况。

暴力算法

阅读完题目之后,首先能想到的解法就是确定一个值 \(nums[i] , 0 \leq i \leq nums.length-1\) ,在剩余的序列中找到 \(target-nums[i]\) 。

解题代码

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        for (int i = 0 ; i < nums.size() - 1 ; i ++) {
            /* j 从 i+1 开始,是因为两个下标不能相同,题目有说明*/
            for (int j = i + 1 ; j < nums.size() ; j++) {
                if ( nums[j] == target - nums[i]) {
                    return {i , j};
                }
            }
        }
        return {};
    }
};

复杂度分析

设 \(nums\) 的长度为 \(n\) ,可以得到等式

\[\begin{equation}\begin{aligned} Complex &= \underbrace{(n-1) + (n-2) + (n-3) +\cdots + 1}_{n-1} = \frac{[1 + (n-1)]\times(n-1)}{2} \\ &= \frac{n^2-n}{2} = \frac{1}{2}n^2 -\frac{1}{2}n. \end{aligned}\end{equation} \]

因此\(\mathcal{O}(Complex) = \mathcal{O}(\frac{1}{2}n^2 -\frac{1}{2}n) = \mathcal{O}(n^2)\)

我们在刚开始刷题的时候,可以先试着自己写出暴力算法,然后分析一下时间复杂度,再尝试其他解题方法。

由暴力算法可以得知,主要的时间消耗是在寻找 \(target-nums[i]\) 上,如果能降低寻找 \(target-nums[i]\) 的时间,就能实现一个时间复杂度小于 \(\mathcal{O}(n^2)\) 的算法。

因此我们考虑用 哈希表 来解决这一问题 。

哈希表算法

最开始接触到哈希表思想是从桶排序算法,它的典型思想是以空间换时间,哈希表的时间复杂度为\(\mathcal{O}(1)\) 。

我们可以将数组分为两部分,如下图:

image

解题代码

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> idx;

        for (int j = 0 ; j < nums.size() ; j++) {
            auto it = idx.find(target-nums[j]);
            if ( it != idx.end()) {
                return { it->second , j};
            }
            idx[nums[j]] = j;
        }
        return {};
    }
};

复杂度分析

设 \(nums\) 的长度为 \(n\) ,可以得到时间复杂度等式

\[\begin{equation}\begin{aligned} \mathcal{O}(Complex) &= \mathcal{O}(\text{哈希查找}) + \mathcal{O}(\text{遍历})\\ &=\mathcal{O}(1) + \mathcal{O}(n) = \mathcal{O}(n+1)\\ &= \mathcal{O}(n). \end{aligned}\end{equation} \]

空间复杂度为 \(\mathcal{O}(n)\).

标签:target,nums,复杂度,leq,哈希,mathcal,LeetCode,两数
From: https://www.cnblogs.com/whtmomo/p/18344917

相关文章

  • leetcode数论(2453. 摧毁一系列目标)
    前言经过前期的基础训练以及部分实战练习,粗略掌握了各种题型的解题思路。现阶段开始专项练习。数论包含最大公约数(>=2个数)、最大公约数性质、最小公倍数、区间范围质因素计数(最下间隔)、质因素分解、判断质数、平方根、立方根、互质、同余等等。描述给你一个下标从 0......
  • leetcode数论(326. 3 的幂)
    前言经过前期的基础训练以及部分实战练习,粗略掌握了各种题型的解题思路。现阶段开始专项练习。数论包含最大公约数(>=2个数)、最大公约数性质、最小公倍数、区间范围质因素计数(最下间隔)、质因素分解、判断质数、平方根、立方根、互质、同余等等。描述给定一个整数,写一个......
  • leetcode力扣第29题:两数相除
    这题看似简单,实则一点也不难(不是),实则还是比较困难。最简单的做法是直接用减法,不停循环计数,最后统计减多少次能成。如果被除数是2^31-1或差不多大小的数,而除数是1差不多大小的数,那循环减法要执行的次数太多,一定会超时。所以一定要有更好的思路(1)通过二分法查找可能的商(2)对于......
  • LeetCode 1631. Path With Minimum Effort
    原题链接在这里:https://leetcode.com/problems/path-with-minimum-effort/description/题目:Youareahikerpreparingforanupcominghike.Youaregiven heights,a2Darrayofsize rowsxcolumns,where heights[row][col] representstheheightofcell (row,c......
  • day32【LeetCode力扣】541. 反转字符串 II
    day32【LeetCode力扣】541.反转字符串II1.题目描述给定一个字符串s和一个整数k,从字符串开头算起,每计数至2k个字符,就反转这2k字符中的前k个字符。如果剩余字符少于k个,则将剩余字符全部反转。如果剩余字符小于2k但大于或等于k个,则反转前k个字符,其余字符......
  • LeetCode面试150——13罗马数字转整数
    题目难度:简单默认优化目标:最小化平均时间复杂度。Python默认为Python3。目录1题目描述2题目解析3算法原理及代码实现3.1模拟法参考文献1题目描述罗马数字包含以下七种字符:I,V,X,L,C,D和M。字符    数值I      1V    ......
  • 【Python】Python中的输入与输出——内附Leetcode【151.反转字符串中的单词】的C语言
    输入与输出导读一、Python中的输出1.1基本用法1.2格式化输出1.3通过`:`格式化值的输出1.4其它格式化输出二、Python中的输入2.1基本用法2.2`split()`方法2.3split()习题演练结语导读大家好,很高兴又和大家见面啦!!!在上一篇内容中我们介绍了Python中的数据类......
  • leetcode200. 岛屿数量C++题解,精美图例和流程图,一题带你弄懂图的dfs遍历算法
    leetcode200.岛屿数量给你一个由‘1’(陆地)和‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。示例1:输入:grid=[[“1”,“1”,“1”,......
  • [LeetCode] 2053. Kth Distinct String in an Array
    Adistinctstringisastringthatispresentonlyonceinanarray.Givenanarrayofstringsarr,andanintegerk,returnthekthdistinctstringpresentinarr.Iftherearefewerthankdistinctstrings,returnanemptystring"".Notethat......
  • LeetCode 热题 HOT 100 (017/100)【宇宙最简单版】
    【链表】No.0148排序链表【中等】......