題目連結:
題目意譯:
你被給定一個非負整數陣列 nums。
我們定義子陣列 nums[l..r] 的分數(其中 l ≦ r)為 nums[l] AND nums[l + 1] AND ... AND nums[r],其中 AND 為按位元 AND 之操作。
考慮將陣列分成一個或多個子陣列來滿足以下條件:
陣列中每一個元素屬於恰好其中一個子陣列。
子陣列的分數總和最小化。
回傳在滿足條件下最多可以切出來的子陣列數量。
一個子陣列為一個陣列中的一個連續部份。
限制:
1 ≦ nums.length ≦ 10 ^ 5
0 ≦ nums[i] ≦ 10 ^ 6
範例測資:
範例 1:
輸入: nums = [1,0,2,0,1,2]
輸出: 3
解釋: 我們可以將陣列分成以下子陣列:
- [1,0]。此子陣列的分數為 1 AND 0 = 0。
- [2,0]。此子陣列的分數為 2 AND 0 = 0。
- [1,2]。此子陣列的分數為 1 AND 2 = 0。
分數總和為 0 + 0 + 0 = 0,其值為我們最小可得到的值。
可以證明無法切成多於 3 個子陣列來得到總分數 0。所以我們回傳 3。
範例 2:
輸入: nums = [5,7,1,3]
輸出: 1
解釋: 我們可以將陣列切成一個子陣列:[5,7,1,3],其分數值為 1,其值為我們最小可得到的值。
可以證明無法切成多於 1 個子陣列來得到總分數 1。所以我們回傳 1。
解題思維:
首先,算出 nums 所有元素 AND 在一起的值,令其值為 X。
可以看到如果 X 非零,則所有可能子陣列的分數都不可能為零(否則 X 應為零);因此此時將 nums 拆分成超過一個的子陣列必定無法得到最小的分數總和。因此此時答案即為 1。
而如果 X 恰好是零,則因為每一個元素只會在恰好一個子陣列中,使得我們可以從 nums[0] 開始一路往後 AND 直到結尾為零。一碰到零之後,再從下一個元素開始一路往後 AND 直到下一個零出現。以此類推直到所有元素掃完為止。
那如果最後一段 AND 完不是零呢?那直接回頭接回到前一次零(這必定存在,因為 X 為零)即可。而因為我們只在乎可以切幾個子陣列出來,因此實際上不需要做這個回頭的動作。
所以,此時的所求即為上述過程中碰到結果值為零之次數。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。