2021-08-12 LeetCode 1442

LeetCode 1442

鏈接:https://leetcode.com/problems/count-triplets-that-can-form-two-arrays-of-equal-xor/
參考:花花醬有一個(gè)非常精彩的視頻講解這道題時(shí)間復(fù)雜度不斷地降低https://www.youtube.com/watch?v=30A0Z2KDvaA

方法1:前綴

時(shí)間復(fù)雜度:O(n3)
想法:異或有一些非常好的性質(zhì)澎现,比方說(shuō)a ^ 0 = a, a ^ a = 0, 以及交換律湾笛。那這個(gè)題經(jīng)常刷題的人肯定能想到寫異或的前綴揩徊。當(dāng)你求出這個(gè)前綴數(shù)組來(lái)的時(shí)候,任何一個(gè)區(qū)間內(nèi)的異或值的查詢就變成了O(1),那么根據(jù)題意枚舉i, j, k即可。
代碼:

class Solution {
    public int countTriplets(int[] arr) {
        int n = arr.length;
        int[] prefix = new int[n + 1];
        
        for (int i = 1; i <= n; i++) {
            prefix[i] = prefix[i - 1] ^ arr[i - 1];
        }
        
        int res = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                for (int k = j; k < n; k++) {
                    if ((prefix[k + 1] ^ prefix[j]) == (prefix[j] ^ prefix[i])) {
                        res++;
                    }
                }
            }
        }
        
        return res;
    }
}

方法2:?jiǎn)栴}轉(zhuǎn)化

時(shí)間復(fù)雜度:O(n2)
想法:arr[i] ^ arr[i + 1] ^ ... ^ arr[j - 1] == arr[j] ^ arr[j + 1] ^ ... ^ arr[k]意味著arr[i] ^ arr[i + 1] ^ ... ^ arr[k] == 0,那么我只要求一些區(qū)間紫岩,它的里面的數(shù)異或起來(lái)等于0。這個(gè)題題目條件說(shuō)1 <= arr[i] <= 10^8睬塌,那就是說(shuō)沒有0泉蝌,那就是說(shuō)在前綴數(shù)組prefix里面歇万,沒有連續(xù)的兩個(gè)元素值相同,那就保證了當(dāng)你去找到了里面值相同的元素時(shí)梨与,你找到的這個(gè)區(qū)間長(zhǎng)度至少是2堕花,直接滿足題目要求。因此直接求完prefix之后暴力枚舉i和k即可粥鞋。

class Solution {
    public int countTriplets(int[] arr) {
        int n = arr.length;
        int[] prefix = new int[n + 1];
        
        for (int i = 1; i <= n; i++) {
            prefix[i] = prefix[i - 1] ^ arr[i - 1];
        }
        
        int res = 0;
        
        for (int i = 0; i < n; i++) {
            for (int k = i + 1; k < n; k++) {
                if (prefix[i] == prefix[k + 1]) {
                    res += k - i;
                }
            }
        }
        
        return res;
    }
}

方法3:在方法2的基礎(chǔ)上HashMap

時(shí)間復(fù)雜度:O(n)
想法:其實(shí)如果刷題比較多的話缘挽,上面這種做法求完prefix之后直接來(lái)了個(gè)暴力枚舉i和k會(huì)讓你覺得有些不安,因?yàn)橄喈?dāng)于你是在找里面相同的元素呻粹,感覺用哈希表是能優(yōu)化的壕曼。隱隱想起什么求子數(shù)組和為0啊或者什么其他題目。這個(gè)題果然也是可以用哈希表優(yōu)化成O(n)的等浊。我這里直接引用花花醬的講法腮郊,假設(shè)說(shuō)你遍歷數(shù)組時(shí)有個(gè)類似HashMap的東西,然后對(duì)于異或的前綴prefix數(shù)組筹燕,prefix[i] == prefix[j] == prefix[k]轧飞,那你一開始遍歷到j(luò),知道前面已經(jīng)有一個(gè)跟你現(xiàn)在異或值相同的值了,那這時(shí)候,我最終的答案要加上j - (i + 1)迹卢,那么當(dāng)遍歷到k的時(shí)候滑臊,k跟i直接可以選中間點(diǎn)腻窒,k跟j之間也可以,那會(huì)加上k * 2 - (i + 1 + j + 1)。從這里就會(huì)發(fā)現(xiàn),每次我要加上的這個(gè)值跟兩個(gè)東西有關(guān):1) 前面這個(gè)異或值已經(jīng)出現(xiàn)了多少次了. 2) 前面這些所出現(xiàn)的衔掸,他們的下標(biāo)和是多少。因此開兩個(gè)哈希表freq和sum即可俺抽。

代碼:

class Solution {
    public int countTriplets(int[] arr) {
        int res = 0;
        Map<Integer, Integer> freq = new HashMap<>();
        freq.put(0, 1);
        Map<Integer, Integer> sum = new HashMap<>();
        int prefix = 0;
        
        for (int i = 0; i < arr.length; i++) {
            prefix ^= arr[i];
            res += freq.getOrDefault(prefix, 0) * i - sum.getOrDefault(prefix, 0);
            freq.merge(prefix, 1, Integer::sum);
            sum.merge(prefix, i + 1, Integer::sum);
        }
        
        return res;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末敞映,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子磷斧,更是在濱河造成了極大的恐慌驱显,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瞳抓,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡伏恐,警方通過(guò)查閱死者的電腦和手機(jī)孩哑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)翠桦,“玉大人横蜒,你說(shuō)我怎么就攤上這事胳蛮。” “怎么了丛晌?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵仅炊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我澎蛛,道長(zhǎng)抚垄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任谋逻,我火速辦了婚禮呆馁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘毁兆。我一直安慰自己浙滤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布气堕。 她就那樣靜靜地躺著纺腊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茎芭。 梳的紋絲不亂的頭發(fā)上揖膜,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音骗爆,去河邊找鬼次氨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛摘投,可吹牛的內(nèi)容都是我干的煮寡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼犀呼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼幸撕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起外臂,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤坐儿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后宋光,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體貌矿,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年罪佳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逛漫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赘艳,死狀恐怖酌毡,靈堂內(nèi)的尸體忽然破棺而出克握,到底是詐尸還是另有隱情,我是刑警寧澤枷踏,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布菩暗,位于F島的核電站,受9級(jí)特大地震影響旭蠕,放射性物質(zhì)發(fā)生泄漏停团。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一下梢、第九天 我趴在偏房一處隱蔽的房頂上張望客蹋。 院中可真熱鬧,春花似錦孽江、人聲如沸讶坯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辆琅。三九已至,卻和暖如春这刷,著一層夾襖步出監(jiān)牢的瞬間婉烟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工暇屋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留似袁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓咐刨,卻偏偏與公主長(zhǎng)得像昙衅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子定鸟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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