LeetCode 第1题:两数之和

题目描述

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

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

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

难度

简单

题目链接

https://leetcode.cn/problems/two-sum/

示例

示例 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]

示例 3:

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

提示

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

解题思路

方法一:暴力枚举

最直观的方法是使用两层循环枚举所有可能的数字对。

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 优点:代码简单直观,空间复杂度低
  • 缺点:时间复杂度高,在数组较大时性能较差

具体步骤:

  1. 使用两层循环,外层循环 i 遍历数组的每个元素
  2. 内层循环 j 从 i+1 开始遍历,寻找和为 target 的另一个数
  3. 如果找到 nums[i] + nums[j] == target,返回下标 [i, j]
  4. 如果遍历完没找到,返回空数组

方法二:哈希表

使用哈希表可以将时间复杂度降到 O(n):

  1. 创建一个哈希表,用于存储每个数字和其下标
  2. 遍历数组,对于每个数字 num:
    • 计算补数 (target - num)
    • 如果补数在哈希表中,则找到答案
    • 否则将当前数字和下标加入哈希表
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
  • 优点:时间复杂度低,查找效率高
  • 缺点:需要额外的空间存储哈希表

代码实现

C# 实现(暴力解法)

public class Solution {
public int[] TwoSum(int[] nums, int target) {
// 外层循环遍历每个元素
for (int i = 0; i < nums.Length; i++) {
// 内层循环从i+1开始,避免重复使用同一个元素
for (int j = i + 1; j < nums.Length; j++) {
// 如果找到两个数的和等于target
if (nums[i] + nums[j] == target) {
return new int[] { i, j };
}
}
}
// 如果没有找到符合条件的数对,返回空数组
return new int[0];
}
}

C# 实现(哈希表解法)

public class Solution {
public int[] TwoSum(int[] nums, int target) {
// 创建字典存储数字和对应的索引
Dictionary<int, int> map = new Dictionary<int, int>(); // 遍历数组
for (int i = 0; i < nums.Length; i++) {
// 计算当前数字需要的补数
int complement = target - nums[i]; // 如果字典中存在这个补数,说明找到了答案
if (map.ContainsKey(complement)) {
return new int[] { map[complement], i };
} // 如果当前数字不在字典中,将其添加到字典
if (!map.ContainsKey(nums[i])) {
map.Add(nums[i], i);
}
} // 如果没有找到符合条件的数对,返回空数组
return new int[0];
}
}

执行结果

暴力解法

  • 执行用时:308 ms
  • 内存消耗:42.8 MB

哈希表解法

  • 执行用时:156 ms
  • 内存消耗:43.5 MB

总结与反思

  1. 这是一道经典的入门题目,考察了基本的算法思维
  2. 暴力解法虽然直观,但效率较低
  3. 使用哈希表可以用空间换时间,提高效率
  4. 这道题告诉我们:
    • 在处理查找问题时,哈希表往往是一个很好的选择
    • 有时候可以通过增加空间复杂度来降低时间复杂度
    • 在实际工程中,通常优先考虑时间复杂度,因为内存通常较为充足

相关题目

  • LeetCode 第15题:三数之和
  • LeetCode 第167题:两数之和 II - 输入有序数组
  • LeetCode 第653题:两数之和 IV - 输入二叉搜索树

LeetCode 第1题:两数之和的更多相关文章

  1. leetcode每日一题——两数之和

    题目: 两数之和 难度: 简单 描述: 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 解法: class Solutio ...

  2. 【leetcode】 算法题 两数之和

      问题       给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 1 ...

  3. leetcode刷题--两数之和(简单)

    一.序言 第一次刷leetcode的题,之前从来没有刷题然后去面试的概念,直到临近秋招,或许是秋招结束的时候才有这个意识,原来面试是需要刷题的,面试问的问题都是千篇一律的,只要刷够了题就差不多了,当然 ...

  4. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

  5. Leetcode:0002(两数之和)

    LeetCode:0002(两数之和) 题目描述:给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表.你可以假设除了数字 0 之外,这两 ...

  6. Leetcode(1)两数之和

    Leetcode(1)两数之和 [题目表述]: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标.你可以假设每种输入只会对应一 ...

  7. leetCode刷题 | 两数之和

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

  8. [LeetCode] 1. Two Sum 两数之和

    Part 1. 题目描述 (easy) Given an array of integers, return indices of the two numbers such that they add ...

  9. LeetCode Golang实现 1. 两数之和

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

  10. Leetcode(一)两数之和

    1.两数之和 题目要求: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重 ...

随机推荐

  1. Impala学习--Impala概述,Impala系统架构

    Imapla概述 Impala是Cloudera公司的一个实时海量查询产品.是对于已有Hive产品的补充.Impala采用了和Hive相同的类SQL接口,但并没有采用MapRed框架执行任务,而是采用 ...

  2. 无需配对数据的对比学习图像到图像转换,助力跨域物体检测 | BMVC'24

    来源:晓飞的算法工程笔记 公众号,转载请注明出处 论文: Improving Object Detection via Local-global Contrastive Learning 论文地址:h ...

  3. 再用RNN神经网络架构设计生成式语言模型

    上一篇:<用谷歌经典ML方法方法来设计生成式人工智能语言模型> 序言:市场上所谓的开源大语言模型并不完全开源,通常只提供权重和少量工具,而架构.训练数据集.训练方法及代码等关键内容并未公开 ...

  4. vue 使用 application/x-www-form-urlencoded格式提交数据

    const params = new URLSearchParams();//前端在传参时需要先新建一个URLSearchParams对象,然后将参数append到这个对象中 params.appen ...

  5. 鸿蒙UI开发快速入门 —— part07:组件状态管理之@Prop/@Link装饰器

    1.前言 我们在上一章学习了@State装饰器,@State装饰器的作用范围仅仅在当前组件,接下来,我们讨论如何从父组件中传入参数到子组件,让子组件随着父组件的状态发生变化.本章将要介绍的就是:@Pr ...

  6. 01编程语言简介与C++

    编程语言是编程的工具 计算机系统是分层的 图1: 图2: 编程语言是软件,也是分层的 图3: 图4: 图5: 图6: visual studio.vscode .dev-c++是三种用于C++编程的集 ...

  7. javac 无效的目标发行版: 11

    maven编译出错. JAVA_HOME 设置成了 jdk8,此时 runner 选 11 也是没用的,务必再覆盖掉 JAVA_HOME.

  8. 在 Ubuntu GUI 中以 root 身份登录

    参考:https://zhuanlan.zhihu.com/p/610049537?utm_id=0 有一些桌面用户想以 root 身份登录.这不是什么明智之举,但肯定是可以做到的. 默认情况下,Ub ...

  9. Netty 缓存buffer介绍及使用

    每当你需要传输数据时,它必须包含一个缓冲区.Java NIO API 自带的缓冲区类是相当有限的,没有经过优化,使用 JDK 的ByteBuffer 操作更复杂.缓冲区是一个重要的组建,它是 API的 ...

  10. 绞尽脑汁终于搞定/天地图标注点marker旋转/任意角度旋转/无需引入其他框架

    一.前言说明 在其他地图组件中,标注点marker都是可以设置旋转角度的,这个功能其实非常实用,比如飞机移动轨迹,就是需要旋转飞机头飞行,轮船轨迹移动也是,百度地图和腾讯地图是通过调用setRotat ...