【LeetCode 熱題 100】(一)哈希

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;先來介…