前往
大廳
主題

LeetCode - 2401. Longest Nice Subarray 解題心得

Not In My Back Yard | 2023-07-30 12:00:24 | 巴幣 0 | 人氣 118

題目連結:


題目意譯:
你被給定一個由正整數組成的陣列 nums。

如果在一個子陣列中每一對位於相異位置的元素對按位元 AND (Bitwise AND)後的結果都等於 0 的話,則我們將稱該子陣列為「超讚」。

回傳最長的超讚子陣列之長度。

一個子陣列為一陣列中的連續部分。

注意到長度 1 的子陣列永遠視為超讚。

限制:
1 ≦ nums.length ≦ 10 ^ 5
1 ≦ nums[i] ≦ 10 ^ 9



範例測資:
範例 1:
輸入: nums = [1,3,8,48,10]
輸出: 3
解釋: 最長的超讚子陣列為 [3,8,48]。這個子陣列滿足以下條件:
- 3 AND 8 = 0。
- 3 AND 48 = 0。
- 8 AND 48 = 0。
可以證明沒有更長的超讚子陣列存在,所以我們回傳 3。

範例 2:
輸入: nums = [3,1,5,11,13]
輸出: 1
解釋: 最長的超讚子陣列之長度為 1。任意一個長度 1 的子陣列都可以選。


解題思維:
典型的滑動視窗(Sliding Window)之題型,如這題

假設現在知道以位置 i 作為子陣列結尾,最左可以延伸到 x 使得 nums[x] ~ nums[i] 是一個超讚子陣列。則要推得以位置 i + 1,最左可以延伸到何處(稱其為 x')則很單純。

可以看到 x' 不可能小於 x,因為對於 nums[i] 來說就已經只能到 nums[x] 而已。多加一個 nums[i + 1] 只有可能把能延伸到的位置往右移動。

因為 nums[x] ~ nums[i] 是一個超讚子陣列,根據定義子陣列中每一對數字按位元 AND 之結果皆為 0。因此我們定義一值 mask,其為「所有數字」按位元 OR 之結果,而因為是超讚子陣列,所以 mask 中每一個是 1 的位元只會來自於子陣列中恰好一個數字。

而如果加入 nums[i + 1] 後,nums[i + 1] 與 mask 進行按位元 AND 後得到的結果不是 0,則代表 nums[x] ~ nums[i + 1] 不是一個超讚子陣列。

再加上 x' 必定大於等於 x,所以我們可以試著把 x 往右移動,也就是試試看 nums[x + 1] ~ nums[i] 的 mask 之值與 nums[i + 1] 按位元 AND 的結果是否為 0。如果依舊不是 0 就繼續重複此步驟直到是為止。

此時的 x 值正是我們要找的 x' 之值。將此時的 mask 之值與 nums[i + 1] 按位元 OR 之後便可以繼續用來求下一個位置 i + 2 的答案,以此類推。



而過程中,所有的位置 i 與它們對應的 x 值相減再加 1 便可以得到以位置 i 作為結尾的最長超讚子陣列之長度。取這些長度值之中的最大值即為所求。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作