LeetCode 219 Contains Duplicate II

題目

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.

Example 1:

Input: nums = [1,2,3,1], k = 3
Output: true

Example 2:

Input: nums = [1,0,1,1], k = 1
Output: true

Example 3:

Input: nums = [1,2,3,1,2,3], k = 2
Output: false


解法思路(一)

  • 外層循環(huán)游標(biāo) i[0, nums.length - 1) 間遍歷吩翻,內(nèi)層循環(huán)在 [i + 1, k] 間遍歷嫩痰,暴力解法益缎,當(dāng)然可以乎赴,只不過時間復(fù)雜度是 O(N*K);
O(N) 時間復(fù)雜度的解法
  • 在遍歷開始前入挣,把滑動窗口中 k 個元素先存入一個查找表递惋,由于窗口中的元素有可能是重復(fù)的访惜,所以使用 HashMap 統(tǒng)計(jì)窗口中每個元素出現(xiàn)的頻次;
  • 當(dāng)游標(biāo) i 在遍歷 [0, nums.length - 1) 的時候宙址,只需要 O(1) 的時間就可以在 nums[i] 對應(yīng)的窗口中判斷出是否有與其相等的元素轴脐;

解法實(shí)現(xiàn)(一)

時間復(fù)雜度
  • O(N);
空間復(fù)雜度
  • O(K)抡砂;
關(guān)鍵詞

滑動窗口 哈希表 HashMap 元素可能重復(fù)的查詢表 窗口滑動的邊界判斷

實(shí)現(xiàn)細(xì)節(jié)
  • k >= nums.length 這個邊界的判斷大咱,nums.length 指向數(shù)組最后一個元素的后面,是數(shù)組外的位置注益,如果 k 的范圍超過數(shù)組的邊界碴巾,那么滑動窗口就縮小為最長到數(shù)組的邊界 nums.length - 1
  • 至于 k 的精確語義丑搔,根據(jù)題目中給的例子可以確定厦瓢;
package leetcode._219;

import java.util.HashMap;

public class Solution219_1 {

    public boolean containsNearbyDuplicate(int[] nums, int k) {

        HashMap<Integer, Integer> windowK = new HashMap();

        for (int i = 1; i <= (k >= nums.length ? nums.length - 1 : k); i++) {
            if (windowK.containsKey(nums[i])) {
                windowK.put(nums[i], windowK.get(nums[i]) + 1);
            } else {
                windowK.put(nums[i], 1);
            }
        }

        for (int i = 0; i < nums.length - 1; i++) {
            if (windowK.containsKey(nums[i])) {
                return true;
            } else if(i + k + 1 < nums.length){
                if (windowK.containsKey(nums[i + k + 1])) {
                    windowK.put(nums[i + k + 1], windowK.get(nums[i + k + 1]) + 1);
                } else {
                    windowK.put(nums[i + k + 1], 1);
                }
            }
            if (windowK.containsKey(nums[i+1])) {
                windowK.put(nums[i + 1], windowK.get(nums[i + 1]) - 1);
                if (windowK.get(nums[i + 1]) == 0) {
                    windowK.remove(nums[i + 1]);
                }
            }
        }

        return false;
    }

    public static void main(String[] args) {
//        int[] arr = {1, 2, 3, 1}; int k = 3;
//        int[] arr = {1, 0, 1, 1}; int k = 1;
//        int[] arr = {1, 2, 3, 1, 2, 3}; int k = 2;
        int[] arr = {1}; int k = 1;
//        int[] arr = {99, 99}; int k = 2;
        boolean result = (new Solution219_1()).containsNearbyDuplicate(arr, k);
        System.out.println(result);
    }

}

解法思路(二)

  • 解法思路(一)是“找自己”的元素“追著”窗口跑,解法思路(二)是“找自己”的元素“領(lǐng)著”窗口跑低匙;

解法實(shí)現(xiàn)(二)

時間復(fù)雜度
  • O(n)旷痕;
空間復(fù)雜度
  • O(k);
關(guān)鍵字

哈希表 HashSet

k 的幾何意義
  • “找自己”的元素最多在距離自己第 k 個的位置“找到自己”顽冶;
  • 滑動窗口的長度是 k欺抗;
關(guān)于滑動窗口
  • 滑動窗口的長度是 k
  • 滑動窗口的起點(diǎn)是“找自己”的后一個元素强重;
  • 滑動窗口的終點(diǎn)是距“找自己”第 k 遠(yuǎn)的元素绞呈;
  • 如果滑動窗口被撐到最長贸人,也沒能在其中找到“自己”,那么就要縮短滑動窗口佃声,讓距“找自己”第 k 個元素“出離”滑動窗口艺智,并將“找自己”的元素納入滑動窗口,與滑動窗口右鄰接的元素成為新的“找自己”的元素圾亏;
關(guān)于滑動窗口中的元素為什么可以用 HashSet 盛裝
  • 滑動窗口的長度最大為 k十拣,滑動窗口被撐到最大只有當(dāng)滑動窗口中沒有相等的元素,如果滑動窗口在沒有被撐到最大的時候志鹃,出現(xiàn)了一個滑動窗口中有的元素想進(jìn)入滑動窗口夭问,那它是進(jìn)不去的,因?yàn)樗呀?jīng)找到了“自己”曹铃,算法運(yùn)行結(jié)束缰趋;
package leetcode._219;

import java.util.HashSet;

// 219. Contains Duplicate II
// https://leetcode.com/problems/contains-duplicate-ii/description/
// 時間復(fù)雜度: O(n)
// 空間復(fù)雜度: O(k)
public class Solution219_2 {

    public boolean containsNearbyDuplicate(int[] nums, int k) {

        if(nums == null || nums.length <= 1)
            return false;

        if(k <= 0)
            return false;

        HashSet<Integer> record = new HashSet<Integer>();
        for(int i = 0 ; i < nums.length; i ++){
            if(record.contains(nums[i]))
                return true;

            record.add(nums[i]);
            if(record.size() == k + 1)
                record.remove(nums[i-k]);
        }

        return false;
    }

    private static void printBool(boolean b){
        System.out.println(b ? "True" : "False");
    }

    public static void main(String[] args) {

        int[] nums = {1, 2, 1};
        int k = 1;
        printBool((new Solution219_2()).containsNearbyDuplicate(nums, k));
    }

}

返回 LeetCode [Java] 目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市陕见,隨后出現(xiàn)的幾起案子秘血,更是在濱河造成了極大的恐慌,老刑警劉巖评甜,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灰粮,死亡現(xiàn)場離奇詭異,居然都是意外死亡蜕着,警方通過查閱死者的電腦和手機(jī)谋竖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來承匣,“玉大人蓖乘,你說我怎么就攤上這事∪推” “怎么了嘉抒?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長袍暴。 經(jīng)常有香客問我些侍,道長,這世上最難降的妖魔是什么政模? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任岗宣,我火速辦了婚禮,結(jié)果婚禮上淋样,老公的妹妹穿的比我還像新娘耗式。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布刊咳。 她就那樣靜靜地躺著彪见,像睡著了一般。 火紅的嫁衣襯著肌膚如雪娱挨。 梳的紋絲不亂的頭發(fā)上余指,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機(jī)與錄音跷坝,去河邊找鬼酵镜。 笑死,一個胖子當(dāng)著我的面吹牛柴钻,可吹牛的內(nèi)容都是我干的笋婿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼顿颅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了足丢?” 一聲冷哼從身側(cè)響起粱腻,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎斩跌,沒想到半個月后绍些,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡耀鸦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年柬批,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袖订。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡氮帐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洛姑,到底是詐尸還是另有隱情上沐,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布楞艾,位于F島的核電站参咙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏硫眯。R本人自食惡果不足惜蕴侧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望两入。 院中可真熱鬧净宵,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至刁岸,卻和暖如春脏里,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虹曙。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工迫横, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人酝碳。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓矾踱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親疏哗。 傳聞我的和親對象是個殘疾皇子呛讲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354