代碼訓練LeetCode(23)隨機訪問元素

代碼訓練(23)LeetCode之隨機訪問元素

Author: Once Day Date: 2025年6月5日

漫漫長路,才剛剛開始…

全系列文章可參考專欄: 十年代碼訓練_Once-Day的博客-CSDN博客

參考文章:

  • 380. O(1) 時間插入、刪除和獲取隨機元素 - 力扣(LeetCode)
  • 力扣 (LeetCode) 全球極客摯愛的技術成長平臺

文章目錄

      • 代碼訓練(23)LeetCode之隨機訪問元素
        • 1. 原題
        • 2. 分析
        • 3. 代碼實現
        • 4. 總結

1. 原題

實現RandomizedSet 類:

  • RandomizedSet() 初始化 RandomizedSet 對象
  • bool insert(int val) 當元素 val 不存在時,向集合中插入該項,并返回 true ;否則,返回 false
  • bool remove(int val) 當元素 val 存在時,從集合中移除該項,并返回 true ;否則,返回 false
  • int getRandom() 隨機返回現有集合中的一項(測試用例保證調用此方法時集合中至少存在一個元素)。每個元素應該有 相同的概率 被返回。

你必須實現類的所有函數,并滿足每個函數的 平均 時間復雜度為 O(1)

提示:

  • -231 <= val <= 231 - 1
  • 最多調用 insertremovegetRandom 函數 2 * ``105
  • 在調用 getRandom 方法時,數據結構中 至少存在一個 元素。

示例 1:

輸入
["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"]
[[], [1], [2], [2], [], [1], [2], []]
輸出
[null, true, false, true, 2, true, false, 2]解釋
RandomizedSet randomizedSet = new RandomizedSet();
randomizedSet.insert(1); // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
randomizedSet.remove(2); // 返回 false ,表示集合中不存在 2 。
randomizedSet.insert(2); // 向集合中插入 2 。返回 true 。集合現在包含 [1,2] 。
randomizedSet.getRandom(); // getRandom 應隨機返回 1 或 2 。
randomizedSet.remove(1); // 從集合中移除 1 ,返回 true 。集合現在包含 [2] 。
randomizedSet.insert(2); // 2 已在集合中,所以返回 false 。
randomizedSet.getRandom(); // 由于 2 是集合中唯一的數字,getRandom 總是返回 2 。
2. 分析

題目要求實現一個 RandomizedSet 類,該類包含以下方法:

  1. RandomizedSet() - 初始化對象。
  2. bool insert(int val) - 插入元素 val,如果元素不存在則插入并返回 true,否則返回 false
  3. bool remove(int val) - 移除元素 val,如果元素存在則移除并返回 true,否則返回 false
  4. int getRandom() - 隨機返回集合中的一個元素。保證調用時集合中至少有一個元素,且每個元素有相同的被返回概率。

要求所有操作的平均時間復雜度為 O(1)。

為了滿足該題目的要求,我們可以使用哈希表和數組組合的數據結構:

  1. 數組:用于存儲元素,支持 O(1) 時間復雜度的隨機訪問。
  2. 哈希表:鍵為元素值,值為該元素在數組中的索引,支持 O(1) 時間復雜度的插入和刪除操作。

方法實現細節:

插入 (insert):

  • 檢查哈希表中是否已存在該元素。如果存在,返回 false
  • 將元素添加到數組末尾,并在哈希表中記錄該元素的索引。
  • 返回 true

刪除 (remove):

  • 檢查哈希表中是否存在該元素。如果不存在,返回 false
  • 從數組中移除該元素,為了維持 O(1) 的復雜度,可以將數組最后一個元素移動到被刪除元素的位置,并更新哈希表。
  • 從哈希表中刪除該元素,并更新數組的大小。
  • 返回 true

獲取隨機元素 (getRandom):

  • 從數組中隨機選擇一個索引,然后返回該索引對應的元素。

性能優化關鍵點:

  • 內存管理:合理分配和釋放內存是關鍵,尤其是在 randomizedSetCreaterandomizedSetFree 函數中。
  • 哈希沖突:避免哈希沖突可以提升性能,因此選擇合適的哈希函數和沖突解決機制很重要。
3. 代碼實現
struct entry {int val;int idx;struct entry* next;
};typedef struct {int size;                  // 當前元素數量int array[200000];         // 動態數組存儲元素struct entry* map[100000]; // 哈希表存儲元素到索引的映射
} RandomizedSet;RandomizedSet* randomizedSetCreate() {RandomizedSet* set = malloc(sizeof(RandomizedSet));memset(set, 0x0, sizeof(RandomizedSet));srand(time(NULL)); // 初始化隨機種子return set;
}bool randomizedSetInsert(RandomizedSet* set, int val) {int key = val % 100000;struct entry** prev = &(set->map[key]);struct entry* item = set->map[key];while (item != NULL) {if (item->val == val) {return false;}prev = &(item->next);item = item->next;}item = malloc(sizeof(struct entry));item->val = val;item->next = NULL;item->idx = set->size;*prev = item;set->array[set->size] = val;set->size++;return true;
}bool randomizedSetRemove(RandomizedSet* set, int val) {int key = val % 100000;struct entry** prev = &(set->map[key]);struct entry* item = set->map[key];while (item != NULL) {if (item->val == val) {break;}prev = &(item->next);item = item->next;}if (item == NULL) {return false;}*prev = item->next;int idx = item->idx;free(item);if (idx == set->size - 1) {set->size--;return true;}int lastElement = set->array[set->size - 1];set->array[idx] = lastElement; // 將最后一個元素移動到被刪除元素的位置set->size--;key = lastElement % 100000;item = set->map[key];while (item != NULL) {if (item->val == lastElement) {break;}item = item->next;}item->idx = idx;return true;
}int randomizedSetGetRandom(RandomizedSet* set) {int randomIndex = rand() % set->size;return set->array[randomIndex];
}void randomizedSetFree(RandomizedSet* set) {for (int i = 0; i < 100000; i++) {struct entry* item = set->map[i];while (item != NULL) {struct entry* temp = item->next;free(item);item = temp;}}free(set);
}

這段代碼實現了一個 RandomizedSet 結構,它支持插入、刪除、隨機訪問和銷毀操作。下面分析每部分代碼的功能和設計邏輯。

使用了兩種數據結構:

  • 數組 (array):用于存儲元素值,支持快速通過索引訪問和隨機訪問。
  • 哈希表 (map):鏈地址法解決哈希沖突的哈希表,存儲鍵為元素值,值為該元素在數組中的索引。

分配內存并初始化 RandomizedSet,其中 memset 用于初始化內存區域。

插入操作首先計算哈希鍵值,然后遍歷鏈表檢查元素是否已存在。如果不存在,創建新條目并加入鏈表和數組。

刪除操作查找鏈表中的元素,然后從鏈表和數組中刪除,同時更新相關元素的索引。

通過隨機生成索引來從數組中獲取元素。

釋放哈希表中所有鏈表的內存以及 RandomizedSet 結構的內存。

4. 總結

這個題目主要考察數據結構的靈活應用和操作的優化。通過綜合利用數組和哈希表,我們能夠實現各種操作的平均 O(1) 時間復雜度。對于提升編程能力,重點是掌握各種數據結構的特點及其適用場景,以及如何根據需求選擇和設計最合適的數據結構。

表和數組中刪除,同時更新相關元素的索引。

通過隨機生成索引來從數組中獲取元素。

釋放哈希表中所有鏈表的內存以及 RandomizedSet 結構的內存。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908335.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908335.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908335.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++面試5——對象存儲區域詳解

C++對象存儲區域詳解 核心觀點:內存是程序員的戰場,存儲區域決定對象的生殺大權!棧對象自動赴死,堆對象生死由你,全局對象永生不死,常量區對象只讀不滅。 一、四大地域生死簿 棧區(Stack) ? 特點:自動分配釋放,速度極快(類似高鐵進出站) ? 生存期:函數大括號{}就…

STM32 智能小車項目 L298N 電機驅動模塊

今天開始著手做智能小車的項目了 在智能小車或機器人項目中&#xff0c;我們經常會聽到一個詞叫 “H 橋電機驅動”&#xff0c;尤其是常見的 L298N 模塊&#xff0c;就是基于“雙 H 橋”原理設計的。那么&#xff0c;“H 橋”到底是什么&#xff1f;為什么要用“雙 H 橋”來驅動…

python項目如何創建docker環境

這里寫自定義目錄標題 python項目創建docker環境docker配置國內鏡像源構建一個Docker 鏡像驗證鏡像合理的創建標題&#xff0c;有助于目錄的生成如何改變文本的樣式插入鏈接與圖片如何插入一段漂亮的代碼片生成一個適合你的列表創建一個表格設定內容居中、居左、居右SmartyPant…

MySQL-多表關系、多表查詢

一. 一對多(多對一) 1. 例如&#xff1b;一個部門下有多個員工 在數據庫表中多的一方(員工表)、添加字段&#xff0c;來關聯一的一方(部門表)的主鍵 二. 外鍵約束 1.如將部門表的部門直接刪除&#xff0c;然而員工表還存在其部門下的員工&#xff0c;出現了數據的不一致問題&am…

【 HarmonyOS 5 入門系列 】鴻蒙HarmonyOS示例項目講解

【 HarmonyOS 5 入門系列 】鴻蒙HarmonyOS示例項目講解 一、前言&#xff1a;移動開發聲明式 UI 框架的技術變革 在移動操作系統的發展歷程中&#xff0c;UI 開發模式經歷了從命令式到聲明式的重大變革。 根據華為開發者聯盟 2024 年數據報告顯示&#xff0c;HarmonyOS 設備…

【SSM】SpringMVC學習筆記7:前后端數據傳輸協議和異常處理

這篇學習筆記是Spring系列筆記的第7篇&#xff0c;該筆記是筆者在學習黑馬程序員SSM框架教程課程期間的筆記&#xff0c;供自己和他人參考。 Spring學習筆記目錄 筆記1&#xff1a;【SSM】Spring基礎&#xff1a; IoC配置學習筆記-CSDN博客 對應黑馬課程P1~P20的內容。 筆記2…

借助 Spring AI 和 LM Studio 為業務系統引入本地 AI 能力

Spring AI 1.0.0-SNAPSHOTLM Studio 0.3.16qwen3-4b 參考 Unable to use spring ai with LMStudio using spring-ai openai module Issue #2441 spring-projects/spring-ai GitHub LM Studio 下載安裝 LM Studio下載 qwen3-4b 模型。對于 qwen3 系列模型&#xff0c;測試…

C++學習-入門到精通【13】標準庫的容器和迭代器

C學習-入門到精通【13】標準庫的容器和迭代器 目錄 C學習-入門到精通【13】標準庫的容器和迭代器一、標準模板庫簡介1.容器簡介2.STL容器總覽3.近容器4.STL容器的通用函數5.首類容器的通用typedef6.對容器元素的要求 二、迭代器簡介1.使用istream_iterator輸入&#xff0c;使用…

Vue Router的核心實現原理深度解析

1. Vue Router的基本架構 Vue Router的核心功能是實現前端路由&#xff0c;即在不重新加載頁面的情況下更改應用的視圖。它的基本架構包括&#xff1a; 路由配置&#xff1a;定義路徑與組件的映射關系路由實例&#xff1a;管理路由狀態和提供導航方法路由視圖&#xff1a;渲染…

設計模式——狀態設計模式(行為型)

摘要 狀態設計模式是一種行為型設計模式&#xff0c;核心在于允許對象在內部狀態改變時改變行為。它通過狀態對象封裝不同行為&#xff0c;使狀態切換靈活清晰。該模式包含環境類、抽象狀態類和具體狀態類等角色&#xff0c;具有避免大量分支判斷、符合單一職責和開閉原則等特…

C++ 觀察者模式:設計與實現詳解

一、引言 在現代軟件開發中,組件間的交互與通信是系統設計的核心挑戰之一。觀察者模式(Observer Pattern)作為一種行為設計模式,提供了一種優雅的解決方案,用于實現對象間的一對多依賴關系。本文將深入探討 C++ 中觀察者模式的設計理念、實現方式及其應用場景。 二、觀察…

Windows 賬號管理與安全指南

Windows 賬號管理與安全指南 概述 Windows 賬號管理是系統安全的基礎&#xff0c;了解如何正確創建、管理和保護用戶賬戶對于系統管理員和安全專業人員至關重要。本文詳細介紹 Windows 系統中的賬戶管理命令、隱藏賬戶創建方法以及安全防護措施。 基礎賬戶管理命令 net use…

[藍橋杯]擺動序列

擺動序列 題目描述 如果一個序列的奇數項都比前一項大&#xff0c;偶數項都比前一項小&#xff0c;則稱為一個擺動序列。即 a2i<a2i?1,a2i1 >a2ia2i?<a2i?1?,a2i1? >a2i?。 小明想知道&#xff0c;長度為 mm&#xff0c;每個數都是 1 到 nn 之間的正整數的…

Python 網絡編程 -- WebSocket編程

作者主要是為了用python構建實時網絡通信程序。 概念性的東西越簡單越好理解,因此,下面我從晚上摘抄的概念 我的理解。 什么是網絡通信? 更確切地說&#xff0c;網絡通信是兩臺計算機上的兩個進程之間的通信。比如&#xff0c;瀏覽器進程和新浪服務器上的某個Web服務進程在通…

GM DC Monitor如何實現TCP端口狀態監控-操作分享

本節講解如何通過現有指標提取監控腳本制作自定義的TCP端口監控指標 一、功能介紹 通過提取已有的監控指標的監控命令&#xff0c;來自定義TCP端口的監控指標。 二、配置端口監控 1&#xff09;定位監控腳本 確定腳本及參數如下&#xff1a; check_protocol_tcp.pl --plug…

LabVIEW與Modbus/TCP溫濕度監控系統

基于LabVIEW 開發平臺與 Modbus/TCP 通信協議&#xff0c;設計一套適用于實驗室環境的溫濕度數據采集監控系統。通過上位機與高精度溫濕度采集設備的遠程通信&#xff0c;實現多設備溫濕度數據的實時采集、存儲、分析及報警功能&#xff0c;解決傳統人工采集效率低、環境適應性…

Ntfs!ReadIndexBuffer函數分析之nt!CcGetVirtualAddress函數之nt!CcGetVacbMiss

第一部分&#xff1a; NtfsMapStream( IrpContext, Scb, LlBytesFromIndexBlocks( IndexBlock, Scb->ScbType.Index.IndexBlockByteShift ), Scb->ScbType.Index.BytesPerIndexBuffer, &am…

vite+vue3項目中,單個組件中使用 @use報錯

報錯信息&#xff1a; [plugin:vite:css] [sass] use rules must be written before any other rules.use 官方說明 注意事項&#xff1a; https://sass-lang.com/documentation/at-rules/use/ 樣式表中的 use 規則必須位于所有其他規則&#xff08;除 forward 外&#xff0…

基于VMD-LSTM融合方法的F10.7指數預報

F10.7 Daily Forecast Using LSTM Combined With VMD Method ??F10.7?? solar radiation flux is a well-known parameter that is closely linked to ??solar activity??, serving as a key index for measuring the level of solar activity. In this study, the ??…

React 新項目

使用git bash 創建一個新項目 建議一開始就創建TS項目 原因在Webpack中改配置麻煩 編譯方法:ts compiler 另一種 bable 最好都配置 $ create-react-app cloundmusic --template typescript 早期react項目 yarn 居多 目前npm包管理居多 目前pnpm不通用 icon 在public文件夾中…