LeetCode 第一题: 两数之和

文章目录

  • 第一题: 两数之和
  • 题目描述
    • 示例
  • 解题思路
  • Go语言实现 - 一遍哈希表法
    • C++实现
    • 算法分析
  • 排序和双指针法
    • Go语言实现 - 排序和双指针法
    • C++
    • 算法分析
  • 暴力法
    • Go语言实现 - 暴力法
    • C++
    • 算法分析
  • 二分搜索法
    • Go语言实现 - 二分搜索法
    • C++
    • 算法分析

第一题: 两数之和

题目描述

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

示例

给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

解题思路

  1. 暴力法:双重循环遍历数组中的每个数,寻找是否存在一个数与它相加等于目标值。
  2. 两遍哈希表法:遍历数组,将每个数及其索引存入哈希表,然后再次遍历数组,查找 target - nums[i]​​ 是否在哈希表中。
  3. 一遍哈希表法:遍历数组,对于每个数,查找 target - nums[i]​​ 是否在哈希表中,如果在,直接返回结果;如果不在,将当前数存入哈希表。

截图为Go语言的测试

Go语言实现 - 一遍哈希表法

package main
func twoSum(nums []int, target int) []int {hashTable := make(map[int]int)for i, num := range nums {complement := target - numif index, ok := hashTable[complement]; ok {return []int{index, i}}hashTable[num] = i}return nil
}

C++实现

#include <vector>
#include <unordered_map>class Solution {
public:std::vector<int> twoSum(std::vector<int>& nums, int target) {std::unordered_map<int, int> hashTable;for (int i = 0; i < nums.size(); ++i) {int complement = target - nums[i];if (hashTable.find(complement) != hashTable.end()) {return {hashTable[complement], i};}hashTable[nums[i]] = i;}return {};}
};

算法分析

  • 时间复杂度:O(n),其中 n 是数组中的元素数量。我们只遍历了包含有 n 个元素的列表两次。在哈希表中的操作时间复杂度为 O(1)。
  • 空间复杂度:O(n),所需的额外空间取决于哈希表中存储的元素数量,该表中存储了 n 个元素。
    这个Go语言实现的代码简单易懂,效率较高,适合解决这类问题。

image

排序和双指针法

  1. 首先,创建一个数组,包含原始数组的元素和它们的索引。

  2. 然后,根据数组元素对数组进行排序。

  3. 使用两个指针,一个从开始(最小元素)的位置,另一个从结束(最大元素)的位置。

  4. 比较两个指针指向的元素之和与目标和:

    • 如果和等于目标和,返回两个元素的索引。
    • 如果和小于目标和,移动左侧指针,使它指向一个更大的数。
    • 如果和大于目标和,移动右侧指针,使它指向一个更小的数。
      这种方法的关键在于,排序后我们可以使用双指针高效地找到两个数,使得它们的和等于目标和。

Go语言实现 - 排序和双指针法

package main
import ("sort"
)
type Pair struct {Value intIndex int
}
func twoSum(nums []int, target int) []int {pairs := make([]Pair, len(nums))for i, num := range nums {pairs[i] = Pair{Value: num, Index: i}}sort.Slice(pairs, func(i, j int) bool {return pairs[i].Value < pairs[j].Value})left, right := 0, len(nums)-1for left < right {sum := pairs[left].Value + pairs[right].Valueif sum == target {return []int{pairs[left].Index, pairs[right].Index}} else if sum < target {left++} else {right--}}return nil
}

C++

#include <vector>
#include <algorithm>
#include <utility>class Solution {
public:std::vector<int> twoSum(std::vector<int>& nums, int target) {std::vector<std::pair<int, int>> numWithIndex;for (int i = 0; i < nums.size(); ++i) {numWithIndex.push_back({nums[i], i});}std::sort(numWithIndex.begin(), numWithIndex.end());int left = 0, right = nums.size() - 1;while (left < right) {int sum = numWithIndex[left].first + numWithIndex[right].first;if (sum == target) {return {numWithIndex[left].second, numWithIndex[right].second};} else if (sum < target) {++left;} else {--right;}}return {};}
};

算法分析

  • 时间复杂度:O(nlogn),其中 n 是数组中的元素数量。排序的时间复杂度是 O(nlogn),双指针遍历的时间复杂度是 O(n)。
  • 空间复杂度:O(n),我们需要一个额外的数组来存储元素和它们的索引。
    这种方法在空间复杂度上与哈希表方法相同,但时间复杂度稍高,因为它需要排序。然而,这种方法在不允许修改原数组或需要保持元素原始顺序的情况下可能更有用。

image

暴力法

  1. 使用两个嵌套循环遍历数组中的所有元素对。
  2. 对于每一对元素,检查它们的和是否等于目标和。
  3. 如果找到一对元素的和等于目标和,返回这两个元素的索引。
    这种方法的时间复杂度是 O(n^2),因为它需要对数组中的每一对元素进行一次检查。

Go语言实现 - 暴力法

package main
func twoSum(nums []int, target int) []int {for i := 0; i < len(nums); i++ {for j := i + 1; j < len(nums); j++ {if nums[i] + nums[j] == target {return []int{i, j}}}}return nil
}

C++

#include <vector>class Solution {
public:std::vector<int> twoSum(std::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) {return {i, j};}}}return {};}
};

算法分析

  • 时间复杂度:O(n^2),其中 n 是数组中的元素数量。最坏的情况下,我们需要遍历每个元素与其他元素的组合。
  • 空间复杂度:O(1),我们只需要常数级别的额外空间来存储索引。
    暴力法是一种简单直接的方法,但是对于大型数据集来说,它的效率不高。在实际应用中,通常会优先考虑使用哈希表或排序和双指针法来解决这类问题。

image

二分搜索法

  1. 首先,对数组进行排序,并创建一个新数组来保存排序后元素的原始索引。
  2. 对于数组中的每个元素,使用二分搜索查找 target - nums[i]​。
  3. 如果找到,确保两个元素的原始索引不同,然后返回它们的原始索引。
    这种方法的关键在于,排序后我们可以使用二分搜索高效地找到第二个数。

Go语言实现 - 二分搜索法

package main
import ("sort"
)
func twoSum(nums []int, target int) []int {indexes := make([]int, len(nums))for i := range nums {indexes[i] = i}sort.Slice(indexes, func(i, j int) bool {return nums[indexes[i]] < nums[indexes[j]]})for i := 0; i < len(nums); i++ {left, right := i+1, len(nums)-1complement := target - nums[indexes[i]]for left <= right {mid := left + (right-left)/2if nums[indexes[mid]] == complement {return []int{indexes[i], indexes[mid]}} else if nums[indexes[mid]] < complement {left = mid + 1} else {right = mid - 1}}}return nil
}

C++

#include <vector>
#include <algorithm>
#include <numeric>class Solution {
public:std::vector<int> twoSum(std::vector<int>& nums, int target) {std::vector<int> indexes(nums.size());std::iota(indexes.begin(), indexes.end(), 0);std::sort(indexes.begin(), indexes.end(), [&nums](int i, int j) { return nums[i] < nums[j]; });for (int i = 0; i < nums.size(); ++i) {int left = i + 1, right = nums.size() - 1;int complement = target - nums[indexes[i]];while (left <= right) {int mid = left + (right - left) / 2;if (nums[indexes[mid]] == complement) {return {indexes[i], indexes[mid]};} else if (nums[indexes[mid]] < complement) {left = mid + 1;} else {right = mid - 1;}}}return {};}
};

算法分析

  • 时间复杂度:O(nlogn),其中 n 是数组中的元素数量。排序的时间复杂度是 O(nlogn),二分搜索的时间复杂度是 O(logn),总共进行了 n 次二分搜索。
  • 空间复杂度:O(n),我们需要一个额外的数组来保存索引。
    二分搜索法在空间复杂度上与哈希表方法相同,但时间复杂度稍高,因为它需要排序。这种方法在不允许修改原数组或需要保持元素原始顺序的情况下可能更有用。然而,对于"两数之和"这个问题,哈希表法通常是更优的选择,因为它的时间复杂度更低。

image

C++的实现

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/703735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6.2 认证授权模块 - 继承JWT、网关认证

认证授权模块 - 继承JWT、网关认证 文章目录 认证授权模块 - 继承JWT、网关认证一、JWT1.1 普通令牌1.2 JWT 令牌介绍1.3 测试生成JWT 令牌1.3.1 TokenConfig1.3.2 授权服务器配置 AuthorizationServer1.3.3 WebSecurityConfig 安全管理配置1.3.4 返回信息 1.4 资源服务集成 JW…

《乱弹篇(十九)围炉诗话》

闲来无事&#xff0c;近日浏览中国古代文学书藉&#xff0c;读罢《新嫁娘词》中的一首五言绝句诗&#xff0c;觉得妙趣横生&#xff0c;艺术造诣甚高。今天恰逢春潮寒意还浓&#xff0c;气温很低&#xff0c;笔者雅兴勃发&#xff0c;便开足暖气&#xff0c;也附庸风雅地来一番…

WSL2配置Linux、Docker、VS Code、zsh、oh my zsh(附Docker开机自启设置)

0. 写在前面 本篇笔记来自于UP主麦兜搞IT的合集视频Windows10开发环境搭建中的部分内容 1. 安装WSL2 按照微软官方文档进行操作&#xff0c;当然也可以直接wsl --install 也可以按照 旧版手动安装的步骤 来进行操作 选择安装的是Ubuntu 20.04 LTS 注&#xff1a;WSL默认安装…

抖音视频提取软件使用功能|抖音视频下载工具

我们的抖音视频提取软件是一款功能强大、易于操作的工具&#xff0c;旨在解决用户在获取抖音视频时需要逐个复制链接、下载的繁琐问题。我们的软件支持通过关键词搜索和分享链接两种方式获取抖音视频&#xff0c;方便用户快速找到自己感兴趣的内容。 主要功能模块&#xff1a;…

计算机设计大赛 深度学习图像风格迁移

文章目录 0 前言1 VGG网络2 风格迁移3 内容损失4 风格损失5 主代码实现6 迁移模型实现7 效果展示8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习图像风格迁移 - opencv python 该项目较为新颖&#xff0c;适合作为竞赛课题…

pytorch -- CIFAR10 完整的模型训练套路

网络结构 代码 # CIFAR 10完整的模型训练套路&#xff1a; import torch.optim import torchvision from torch import nn from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterfrom model import *# 1. 准备数据集 train_data torch…

SSM框架学习笔记07 | Spring MVC入门

文章目录 1. HTTP协议2. Spring MVC2.1. 三层架构2.2. MVC&#xff08;解决表现层的问题&#xff09;2.3. 核心组件 3. Thymeleaf3.1. 模板引擎3.2. Thymeleaf3.3. 常用语法 代码 1. HTTP协议 网址&#xff1a;https://www.ietf.org/ &#xff08;官网网址&#xff09; https:…

dolphinscheduler单机版部署教程

文章目录 前言一、安装准备1. 安装条件2. 安装jdk3. 安装MySQL 二、安装dolphinscheduler1. 下载并解压dolphinscheduler2. 修改配置文件2.1 修改 dolphinscheduler_env.sh 文件2.2 修改 application.yaml 文件 3. 配置mysql数据源3.1 修改MySQL安全策略3.2 查看数据库3.3 创建…

使用Docker部署MinIO并结合内网穿透实现远程访问本地数据

文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器&#xff0c;可以在各种环境中运行&#xff0c;例如本地、Docker容器、Kubernetes集群等。它兼…

Pytest教程:一种利用 Python Pytest Hook 机制的软件自动化测试网络数据抓包方法

随着计算机技术的发展&#xff0c;使得网络应用的数量不断增加&#xff0c;因此网络数据抓包成为了网络应用开发和测试中非常重要的一部分。目前&#xff0c;已有许多网络数据抓包工具可供使用&#xff0c;例如 Wireshark、Tcpdump、Fiddler 等&#xff0c;但这些工具需要手动配…

进程的学习

进程基本概念: 1.进程: 程序&#xff1a;存放在外存中的一段数据组成的文件 进程&#xff1a;是一个程序动态执行的过程,包括进程的创建、进程的调度、进程的消亡 2.进程相关命令: 1.top 动态查看当前系统中的所有进程信息&#xff08;根据CPU占用率排序&#xf…

PHY6222系统级SOC蓝牙芯片低功耗高性能蓝牙MESH组网智能家居

简介 PHY6222是一款支持BLE 5.2功能和IEEE 802.15.4通信协议的系统级芯片&#xff08;SoC&#xff09;&#xff0c;集成了超低功耗的高性能多模射频收发机&#xff0c;搭载32-bit ARM?Cortex?-M0处理器&#xff0c;提供64K retention SRAM、可选128K-8M Flash、96KB ROM以及2…

十、线性代数二-线性相关

目录 1、线性相关的概念&#xff1a; 2、线性相关的代数表示&#xff1a; 3、线性相关的判断方法&#xff1a; 理解&#xff1a;线性相关指的是 向量组&#xff08;α1&#xff0c;α2&#xff0c;α3&#xff0c;...&#xff09;的 秩是 小于 k 的元数的&#xff0c;即齐次…

第二节:Vben Admin 登录逻辑梳理和对接后端准备

系列文章目录 上一节&#xff1a;第一节&#xff1a;Vben Admin介绍和初次运行 文章目录 系列文章目录前言项目路径的概述一、登录逻辑梳理loginApi接口查看Mock 二、后端程序对接准备关闭Mock 总结 前言 第一节&#xff0c;我们已经配置了前端环境&#xff0c;运行起来了我们…

文献速递:深度学习--深度学习方法用于帕金森病的脑电图诊断

文献速递&#xff1a;深度学习–深度学习方法用于帕金森病的脑电图诊断 01 文献速递介绍 人类大脑在出生时含有最多的神经细胞&#xff0c;也称为神经元。这些神经细胞无法像我们身体的其他细胞那样自我修复。随着年龄的增长&#xff0c;神经元逐渐死亡&#xff0c;因此变得…

el-form 表单文本标签label增加tooltip提示图标

需求&#xff1a;在el-form表单中&#xff0c;el-form-item的文本标签处增加提示语&#xff1b; 标签&#xff1a;el-form、el-form-item、el-tooltip&#xff1b; 实现&#xff1a; <el-form-item prop"basicScore"><span slot"label"><…

nginx之状态页 日志分割 自定义图表 证书

5.1 网页的状态页 基于nginx 模块 ngx_http_stub_status_module 实现&#xff0c;在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module&#xff0c;否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态 server{…

【Git】Git命令的学习与总结

本文实践于 Learn Git Branching 这个有趣的 Git 学习网站。在该网站&#xff0c;可以使用 show command 命令展示所有可用命令。你也可以直接访问网站的sandbox&#xff0c;自由发挥。 一、本地篇 基础篇 git commit git commit将暂存区&#xff08;staging area&#xff…

采访影视行业人“Sora入局,或将改变游戏规则?”

自OpenAI发布Sora已经过去了半个月&#xff0c;人们对于这个新兴的“文生视频”&#xff08;text-to-video&#xff09;大模型工具都已经有了初步的认识&#xff0c;经过半个月的沉淀&#xff0c;他们也陆续发布了一些更加令人震惊的demo&#xff0c;话不多说&#xff0c;我们先…

Bootstrap引入和使用

Bootstrap 基础用法 目录 Bootstrap 基础用法什么是Bootstrap&#xff1f;引入Bootstrap布局容器栅格系统表格样式表单样式text样式按钮样式图标 什么是Bootstrap&#xff1f; Bootstrap是一个开源的前端框架&#xff0c;用于对HTML和CSS代码进行封装&#xff0c;因此可以直接…