1. 两数之和

class Solution {public int[] twoSum(int[] nums, int target) {int length = nums.length;// 1.声明一个hashmap {nums[i], i}HashMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < length; i++) {int second = target - nums[i];if(map.containsKey(second)){int j = map.get(second);return new int[]{i,j};}map.put(nums[i],i);}return new int[]{};     }
}

这段代码实现了在整数数组 nums 中找到两个数,使它们的和等于给定的目标值 target,并返回这两个数的索引。其解题思路基于 哈希表优化查找效率,具体步骤如下:

解题思路描述:

  1. 初始化哈希表

    • 创建一个 HashMap<Integer, Integer>,键(Key)存储数组元素的值,值(Value)存储该元素的索引。
    • 目标:通过值快速查找对应的索引。
  2. 遍历数组

    • 对每个元素 nums[i],计算其配对值 second = target - nums[i](即满足 nums[i] + second = target 的值)。
  3. 检查配对值是否存在

    • 在哈希表中查找 second
      • 若存在:说明 second 是之前遍历过的某个元素的值,其索引 j = map.get(second) 与当前索引 i 即为解。
      • 直接返回 {i, j}(顺序为 i 在后,j 在前)。
    • 若不存在:将当前值 nums[i] 及其索引 i 存入哈希表,继续遍历。
  4. 遍历结束处理

    • 若循环结束未找到解,返回空数组 {}(题目保证有解,此步为语法完整性)。

关键点分析:

  • 高效查找:哈希表在平均 O(1) 时间内完成 containsKeyget 操作,将整体时间复杂度优化至 O(n)
  • 避免重复使用:先检查配对值再存入当前值,确保不会将同一元素使用两次(例如 target = 4, nums[i] = 2 时,先检查 2 是否已存在,再存入当前 2)。
  • 顺序无关:返回索引顺序取决于遍历顺序(j 为哈希表中存储的较早索引,i 为当前索引)。

示例说明:

  • 输入:nums = [3, 2, 4], target = 6
  • 步骤:
    1. i=0nums[0]=3second=3(6-3),哈希表为空 → 存入 (3,0)
    2. i=1nums[1]=2second=4(6-2),哈希表无 4 → 存入 (2,1)
    3. i=2nums[2]=4second=2(6-4),哈希表存在 2(索引 j=1)→ 返回 {2, 1}

复杂度:

  • 时间复杂度:O(n),遍历数组一次。
  • 空间复杂度:O(n),哈希表存储最多 n 个元素。

此方法以空间换时间,高效解决了“两数之和”问题。

49. 字母异位词分组

class Solution {public List<List<String>> groupAnagrams(String[] strs) {HashMap<String, List<String>> map = new HashMap<>();for (String item : strs) {// 1. 声明字母数组int[] count1 = new int[26];// 2. 将字母转换位对应的ascii 存储到数组下标for (int i = 0; i < item.length(); i++) {char c = item.charAt(i);int poi = c - 'a';count1[poi] = count1[poi] + 1;}// 3. 在将数组下标转换位字母StringBuilder sb = new StringBuilder();for (int i = 0; i < 26; i++) {if(count1[i] != 0){sb.append((char) (i + 'a'));sb.append(count1[i]);}}// 4. 判断map中键中是否包含String key = sb.toString();List<String> list1 = map.getOrDefault(key, new LinkedList<>());list1.add(item);map.put(key, list1);}List<List<String>> list = new LinkedList<>(map.values());return list;}
}

解题思路描述

这段代码实现了将一组字符串按字母异位词(Anagram) 分组的功能。字母异位词指字母相同但排列不同的字符串(如 “eat” 和 “tea”)。核心思路是 为每个字符串生成唯一的特征编码作为哈希表的键,具体步骤如下:


1. 初始化哈希表
HashMap<String, List<String>> map = new HashMap<>();
  • 键(Key):字符串的特征编码(字母出现频次的唯一标识)
  • 值(Value):所有具有相同特征编码的字符串组成的列表

2. 遍历所有字符串

对每个字符串 item 执行以下操作:

for (String item : strs) {// 步骤2.1 ~ 2.4
}
2.1 统计字母频次
int[] count1 = new int[26];
for (int i = 0; i < item.length(); i++) {char c = item.charAt(i);int poi = c - 'a';  // 将字母映射到 0-25 的索引count1[poi]++;      // 对应字母计数+1
}
  • 创建长度 26 的数组(对应 a-z)
  • 遍历字符串中的每个字符,在数组中记录其出现次数
2.2 生成特征编码(关键步骤)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 26; i++) {if(count1[i] != 0){sb.append((char) (i + 'a')); // 添加字母sb.append(count1[i]);        // 添加出现次数}
}
String key = sb.toString();
  • 将统计数组转换为唯一字符串标识(如 “a2b1” 表示 a 出现 2 次,b 出现 1 次)
  • 为什么有效
    字母异位词的统计结果相同 → 生成的 key 相同
    非字母异位词统计结果不同 → 生成的 key 不同
2.3 分组存储到哈希表
List<String> list1 = map.getOrDefault(key, new LinkedList<>());
list1.add(item);
map.put(key, list1);
  • key 不存在:创建新列表
  • key 已存在:获取现有列表
  • 将当前字符串添加到对应列表

3. 返回分组结果
return new LinkedList<>(map.values());
  • 哈希表的 values() 就是所有分组结果
  • 直接转换为列表返回(每个子列表是一组字母异位词)

关键优势

  1. 精确分组
    通过字母频次统计确保只有字母异位词共享同一 key
  2. 避免排序
    相比对每个字符串排序(O(klogk)),统计频次只需 O(k)(k 为字符串长度)
  3. 哈希表高效操作
    插入和查询操作均摊时间复杂度 O(1)

复杂度分析

  • 时间复杂度:O(n × k)
    • n:字符串数组长度
    • k:最长字符串长度(每个字符串需遍历统计)
  • 空间复杂度:O(n × k)
    • 哈希表存储所有字符串的特征编码和分组列表

示例说明

输入["eat", "tea", "tan"]
处理过程

  1. “eat” → 统计:a1,e1,t1 → 特征码:“a1e1t1”
  2. “tea” → 统计:a1,e1,t1 → 特征码:“a1e1t1” → 与 “eat” 同组
  3. “tan” → 统计:a1,n1,t1 → 特征码:“a1n1t1” → 新分组
    输出[ ["eat","tea"], ["tan"] ]

128. 最长连续序列

class Solution {public int longestConsecutive(int[] nums) {int max_long = 0;Set<Integer> hashSet = new HashSet<>();for (int num : nums) {hashSet.add(num);}for (int num : hashSet) {// 1.判断当前的前一位是否在集合中if(!hashSet.contains(num - 1)){int curr_num = num;int current_long = 1;// 2.全局最大的子序列和当前子序列长度while (hashSet.contains(curr_num + 1)){curr_num = curr_num + 1;current_long = current_long + 1;}max_long = Math.max(current_long, max_long);}}return max_long;}
}

解题思路描述

这段代码实现了在未排序整数数组中寻找最长连续序列长度的功能。核心思路是 利用哈希集合实现高效查找,并通过 跳过非连续序列起点 避免重复计算,具体步骤如下:


1. 初始化哈希集合
Set<Integer> hashSet = new HashSet<>();
for (int num : nums) {hashSet.add(num);
}
  • 将所有数字存入哈希集合,实现 O(1) 时间复杂度的查找
  • 自动去除重复元素,避免冗余处理

2. 寻找连续序列起点
for (int num : hashSet) {if(!hashSet.contains(num - 1)) { // 关键判断// 处理连续序列...}
}
  • 核心思想:只从连续序列的起点开始计算
  • 判断条件:num-1 不存在于集合中 → 说明 num 是某个连续序列的最小值(起点)
  • 为什么有效
    若非起点(如 num=3num-1=2 存在),说明它属于某个更长序列的中间部分,后续会被起点覆盖计算

3. 扩展连续序列
int curr_num = num;
int current_long = 1;
while (hashSet.contains(curr_num + 1)) {curr_num++;          // 移动到下一个数字current_long++;      // 序列长度+1
}
  • 从起点 num 开始向后扩展序列(num, num+1, num+2,...
  • 每找到一个连续后继数字:
    • 移动当前数字指针 curr_num
    • 增加当前序列长度 current_long
  • curr_num+1 不存在时,序列终止

4. 更新全局最大值
max_long = Math.max(current_long, max_long);
  • 比较当前序列长度与历史最大值
  • 始终保持 max_long 为遍历过程中的最大序列长度

5. 返回结果
return max_long;
  • 返回全局最长连续序列长度

关键优势

  1. 高效去重
    使用 HashSet 自动处理重复元素,避免无效计算
  2. 起点优化策略
    仅从序列起点开始扩展,确保每个连续序列只计算一次
  3. 时间复杂度优化
    看似嵌套循环,实际每个元素最多被访问两次(集合构建+序列扩展),整体 O(n) 复杂度

复杂度分析

  • 时间复杂度:O(n)
    • 集合构建:O(n)
    • 序列扩展:每个元素最多被内层循环访问一次
  • 空间复杂度:O(n)
    • 哈希集合存储所有元素

示例说明

输入[100, 4, 200, 1, 3, 2]
处理过程

  1. 构建集合:{1, 2, 3, 4, 100, 200}
  2. 遍历元素:
    • 10099不存在 → 起点 → 向后扩展:101不存在 → 长度=1
    • 43存在 → 非起点 → 跳过
    • 200199不存在 → 起点 → 向后扩展:201不存在 → 长度=1
    • 10不存在 → 起点 → 向后扩展:2,3,4存在 → 5不存在 → 长度=4
    • 23:非起点 → 跳过
  3. 返回最大值:4(序列 1→2→3→4

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

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

相关文章

PMOS快速关断电路、PMOS加速关断电路

[电源系列]二、低成本MOS快速关断电路原理分析 MOS的减速加速电路设计 分享一个微碧在网上看到的电路情况 加速电路1 PMOS关断时间较长。 当用100kHz的频率驱动PMOS时&#xff0c;PMOS G极的电压信号并不是一个脉冲波&#xff0c;PMOS一直处于线性放大的状态&#xff0c;并且…

Docker笔记(基本命令、挂载本地gpu、Dockerfile文件配置、数据挂载、docker换源)

Docker 主要用于环境搭建以及服务部署 基本命令 1.查看镜像 docker images 2.查看容器 docker ps # 查看容器仅仅为查看运行状态的容器 docker ps -a # 查看所有状态的容器3.退出容器 exit4.删除镜像、容器 docker rm 镜像ID docker rm 容器ID docker rm -f 容器ID # 强制删除…

算法竞赛阶段二-数据结构(37)数据结构循环链表模拟实现

之前单链表中&#xff0c;数组全初始化为0&#xff0c;末尾最后一个next 存的就是0&#xff0c;指向的就是头节点循环链表的基本概念循环链表是一种特殊的链表&#xff0c;其尾节点的指针域指向头节点&#xff0c;形成一个闭环。与普通单链表相比&#xff0c;循环链表的遍历需要…

20250727让飞凌OK3576-C开发板在Rockchip的原厂Android14下通过耳机播音

20250727让飞凌OK3576-C开发板在Rockchip的原厂Android14下通过耳机播音 2025/7/27 23:28缘起&#xff1a;很容易知道 飞凌OK3576-C开发板 使用的声卡芯片是 NAU88C22YG 新唐科技(NUVOTON) NAU8822LYG NAU88C22YG 新唐立体声音频编解码芯片原理图&#xff1a;OK3576-C V1.2_202…

正向代理和反向代理的理解

**正向代理&#xff08;Forward Proxy&#xff09;和反向代理&#xff08;Reverse Proxy&#xff09;**是两种不同类型的代理服务器&#xff0c;它们在数据传输过程中扮演的角色、使用场景以及工作方式都有所不同。 正向代理&#xff08;Forward Proxy&#xff09; 定义与作用&…

Java 后端 Cookie Session Token会话跟踪技术

概述 会话从字面理解就是"两方交流"&#xff0c;那问题就来了&#xff0c;HTTP&#xff08;超文本传输协议&#xff09;里面的"传输"不就包含了"两方交流"的意思吗&#xff1f;为什么要多此一举提出会话技术呢&#xff1f; 谈到这个&#xff0c;…

智谱AI GLM大模型 GLM-4-Plus的快速使用 ChatOpenAI类来调用GLM-4模型

智谱AIGLM-4&#xff0c;2024年1月16日发布的第四代基座大模型&#xff0c;其整体性能相较前代提升近60%&#xff0c;多维度指标逼近OpenAI的GPT-4水平。该模型支持128K上下文窗口&#xff08;约300页文本处理能力&#xff09;&#xff0c;在长文本信息处理中实现100%精度召回。…

AsyncLocal浅复制的问题解决方案

针对C#中AsyncLocal<T>浅复制问题&#xff0c;以下是几种主要的解决方案&#xff1a; 1. 使用不可变对象&#xff08;推荐&#xff09; 将存储在AsyncLocal<T>中的对象设计为不可变的&#xff0c;避免修改共享状态&#xff1a; public class ImmutableUserContext …

IIS发布.NET9 API 常见报错汇总

记录工作过程中发现的IIS常见错误。 1. HTTP Error 500.19 - Internal Server Error .NET 9 API --》vs打包方式如下&#xff1a; 发布到IIS后报错HTTP Error 500.19 - Internal Server Error。 解决方案&#xff1a; 下载ASP.NET Core Hosting Bundle&#xff08;ASP.NET Co…

Google Chrome V8< 13.7.120 沙箱绕过漏洞

【严重】Google Chrome V8< 13.7.120 沙箱绕过漏洞 漏洞描述 V8 是 Google 开发的一款开源高性能 JavaScript 和 WebAssembly 引擎&#xff0c;广泛用于 Chrome 浏览器和 Node.js 等项目中。 受影响版本中&#xff0c;JsonParser::MakeString 函数在处理长度为 1 的转义字…

基于Spring Boot和Vue电脑维修平台整合系统的设计与实现

用户&#xff1a;注册&#xff0c;登录&#xff0c;在线报修&#xff0c;维修接单&#xff0c;维修报告&#xff0c;维修评价&#xff0c;个人资料维修工&#xff1a;登录&#xff0c;在线报修&#xff0c;维修接单&#xff0c;维修报告&#xff0c;维修评价&#xff0c;通知公…

InsightFace(RetinaFace + ArcFace)人脸识别项目(预训练模型,鲁棒性很好)

背景介绍 这是一个 简单的人脸识别项目&#xff0c;用 FastApi 在本地实现&#xff0c;使用预训练模型&#xff0c;直接可用。 新方案比之前的FaceNet强太多了&#xff0c;甚至不用数据增强等操作&#xff0c;就可以识别戴眼镜、不戴眼镜、歪着的人脸等。 充分证明了选型的重要…

App Inventor 2 使用 MaterialIcons 图标字体,快捷展示专业图标

平时布局的话&#xff0c;如果要使用图标&#xff0c;一般需要去找 png 图片&#xff0c;且透明背景的。如果需要根据不同常见图标进行变色的话&#xff0c;就需要准备多张不同样式的图标&#xff0c;还要考虑图片的分辨率等等因素&#xff0c;非常的麻烦。 这时&#xff0c;如…

C语言——关于指针(逐渐清晰版)

为了更好地理解本篇文章的知识内容&#xff0c;读者可以将以下文章作为补充知识进行阅读 &#xff1a; C语言————原码 补码 反码 &#xff08;超绝详细解释&#xff09;-CSDN博客 C语言————二、八、十、十六进制的相互转换-CSDN博客 C语言————斐波那契数列的理解…

SVG 在线编辑器

SVG 在线编辑器 引言 随着互联网技术的发展&#xff0c;矢量图形在网页设计和数据可视化中扮演着越来越重要的角色。SVG&#xff08;可缩放矢量图形&#xff09;因其文件小、无限缩放不模糊的特性&#xff0c;成为了网页设计中常用的图形格式。SVG 在线编辑器的出现&#xff0c…

libpostproc 已经从 ffmpeg 中移除,导致编译 ffmpeg 时没有 libpostproc

今天编译 ffmpeg 时突然发现 libpostproc 不见了&#xff0c;-enable-postproc 也变成了非法的选项。用搜索引擎搜索相关信息找不到一点&#xff0c;于是去 github 看。 从提交记录可以看到 libpostproc 已经被移除了 链接 主线中已经看不到了 libpostproc 这个目录了

基于 Dell PowerEdge T440 搭建的 Proxmox VE 配置 RTX 3060 显卡直通虚拟机、切换直通

基于 Dell PowerEdge T440 搭建的 Proxmox VE 配置 RTX 3060 显卡直通虚拟机、切换直通 文章目录 基于 Dell PowerEdge T440 搭建的 Proxmox VE 配置 RTX 3060 显卡直通虚拟机、切换直通 1. 前言 2. 前提条件 3. 配置步骤 3.1. 启用 VT-d 3.2. 激活 IOMMU 3.3. 添加 VFIO 模块 …

如何解决pip安装报错ModuleNotFoundError: No module named ‘voila’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘voila’问题 摘要 在开发过程中&#xff0c;我们常常会遇到pip安装包时出现各种错误&#xff0c;特别是在使用PyCharm进行开发时。本文将详细介绍如何解决安装…

[spring6: @EnableWebMvc]-源码分析

源码 EnableWebMvc EnableWebMvc 是用于启用 Spring MVC 的注解&#xff0c;它通过导入 DelegatingWebMvcConfiguration 来加载默认的 MVC 配置&#xff0c;同时允许开发者通过实现 WebMvcConfigurer 接口来自定义部分配置&#xff1b;若需更高阶的控制&#xff0c;则可直接继承…

Jmeter的元件使用介绍:(四)前置处理器详解

Jmeter的前置处理器可以用来在取样器执行前做一些数据准备操作&#xff0c;也需要注意使用的作用域问题。常用的前置处理器有&#xff1a;用户参数、BeanShell预处理器、JDBC预处理器。一、用户参数 【用户参数】与前面介绍过的【用户定义的变量】有相似之处&#xff0c;先来介…