leetcode 380. 常數(shù)時間插入、刪除和獲取隨機元素

leetcode 380. 常數(shù)時間插入跷究、刪除和獲取隨機元素

題目要求我們實現(xiàn)一個數(shù)據(jù)結(jié)構(gòu)來支持插入、刪除和獲取隨機元素的時間復(fù)雜度都在O(1)之內(nèi)照藻。

難點和突破點:

我們都知道數(shù)組通過索引下標進行訪問是很快的饺鹃,但插入、刪除就不一樣了条霜,比如插入操作催什,需要在插入元素后,將插入位置后的所有元素都向后移動宰睡,以保證內(nèi)存的緊湊蒲凶、連續(xù)性,這需要O(n)的平均時間復(fù)雜度拆内。仔細想想旋圆,這個平均復(fù)雜度里面,最優(yōu)的復(fù)雜度是多少麸恍?

答案是O(1)灵巧,就是操作數(shù)組尾部元素時搀矫,可以達到O(1)的時間復(fù)雜度,對于插入尾部的操作刻肄,因為插入后本身就是數(shù)組的最后一個元素瓤球,所以不需要再移動后面的元素,而對于刪除操作亦是如此敏弃,刪除后不需要再將后面元素向前移動卦羡。

既然知道了操作尾部可以得到最優(yōu)的時間復(fù)雜度,那么我們要做的麦到,就是想辦法在每次的插入绿饵、刪除操作時,都只操作數(shù)組尾部瓶颠,以避免數(shù)據(jù)遷移拟赊;

抓住了這個特點,我們可以考慮用hash表來對val→index做一層映射:

1粹淋、對于插入操作要门,我們直接使用封裝好的ArrayList.add(T t)方法(只要不觸發(fā)擴容,那么該方法可以讓每次插入操作都插入到數(shù)組的尾部廓啊,為O(1)的時間復(fù)雜度)欢搜,同時我們把插入的元素以val→index(因為每次都是插入到最后,因此index就是數(shù)組尾部下標)的形式放入hash表中谴轮,后續(xù)刪除操作需要用到炒瘟;

2、對于刪除操作第步,我們要做的疮装,就是每次將數(shù)組尾部的元素lastVal與當(dāng)前要刪除的元素val的位置做一次調(diào)換(通過hash表找到val在數(shù)組中的索引下標),然后清空尾部粘都,釋放內(nèi)存即可廓推,做完這步后,還需要維護一下hash表翩隧,把目標元素占用的k-v對刪除掉樊展,同時更新lastVal在hash表中的索引映射。

3堆生、對于獲取隨機元素专缠,我們只需要在根據(jù)下標獲取元素時,對size做一個random后作為下標淑仆,即可隨機拿到一個元素涝婉。

代碼如下:

public class RandomizedSet {
        
    // 存儲所有val
    List<Integer> nums ;
    // val->index哈希表,映射每個val在nums中的索引位置
    Map<Integer, Integer> valToIndex;
    Random random;

    public RandomizedSet() {
        nums = new ArrayList<>();
        valToIndex = new HashMap<>();
        random = new Random();
    }

    public boolean insert(int val) {
        // 存在直接返回
        if (valToIndex.containsKey(val)) {
            return false;
        }
        // 直接添加到list中蔗怠,并用hash表記錄val在list中的下標
        nums.add(val);
        valToIndex.put(val, nums.size() - 1);
        return true;
    }

    public boolean remove(int val) {
        if (!valToIndex.containsKey(val)) {
            return false;
        }
        // 1墩弯、找出val在nums中的索引
        Integer valIdx = valToIndex.get(val);
        // 2吩跋、取出nums尾部元素,替換val渔工,并刪除nums尾部(關(guān)鍵代碼)
        Integer lastVal = nums.get(nums.size() - 1);
        nums.set(valIdx, lastVal);
        nums.remove(nums.size() - 1);
        // 3锌钮、更新索引hash表,并remove掉val占用的entry
        valToIndex.put(lastVal, valIdx);
        valToIndex.remove(val);
        return true;
    }

    public int getRandom() {
        return nums.get(random.nextInt(nums.size()));
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涨缚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子策治,更是在濱河造成了極大的恐慌脓魏,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件通惫,死亡現(xiàn)場離奇詭異茂翔,居然都是意外死亡,警方通過查閱死者的電腦和手機履腋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門珊燎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人遵湖,你說我怎么就攤上這事悔政。” “怎么了延旧?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵谋国,是天一觀的道長。 經(jīng)常有香客問我迁沫,道長芦瘾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任集畅,我火速辦了婚禮近弟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挺智。我一直安慰自己祷愉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布赦颇。 她就那樣靜靜地躺著谣辞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沐扳。 梳的紋絲不亂的頭發(fā)上泥从,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音沪摄,去河邊找鬼躯嫉。 笑死纱烘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的祈餐。 我是一名探鬼主播擂啥,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼帆阳!你這毒婦竟也來了哺壶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蜒谤,失蹤者是張志新(化名)和其女友劉穎山宾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鳍徽,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡资锰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了阶祭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绷杜。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖濒募,靈堂內(nèi)的尸體忽然破棺而出鞭盟,到底是詐尸還是另有隱情,我是刑警寧澤瑰剃,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布懊缺,位于F島的核電站,受9級特大地震影響培他,放射性物質(zhì)發(fā)生泄漏鹃两。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一舀凛、第九天 我趴在偏房一處隱蔽的房頂上張望俊扳。 院中可真熱鬧,春花似錦猛遍、人聲如沸馋记。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梯醒。三九已至,卻和暖如春腌紧,著一層夾襖步出監(jiān)牢的瞬間茸习,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工壁肋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留号胚,地道東北人籽慢。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像猫胁,于是被迫代替她去往敵國和親箱亿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容