題目連結:
題目意譯:
你被給定一個索引值從 0 開始數的正整數陣列 nums。
將一個陣列分成一個或多個連續子陣列的一個「分割」是「好的」,代表著沒有任兩個子陣列包含著相同的數字。
回傳 nums 的好分割之數量。
由於答案可能很大,先將其模 10 ^ 9 + 7 後再回傳。
限制:
1 ≦ nums.length ≦ 10 ^ 5
1 ≦ nums[i] ≦ 10 ^ 9
範例測資:
範例 1:
輸入: nums = [1,2,3,4]
輸出: 8
解釋: 8 種好分割為:([1], [2], [3], [4]) 、 ([1], [2], [3,4]) 、 ([1], [2,3], [4]) 、 ([1], [2,3,4]) 、 ([1,2], [3], [4]) 、 ([1,2], [3,4]) 、 ([1,2,3], [4]) 和 ([1,2,3,4])。
範例 2:
輸入: nums = [1,1,1,1]
輸出: 1
解釋: 唯一一個好分割為:([1,1,1,1])。
範例 3:
輸入: nums = [1,2,1,3]
輸出: 2
解釋: 2 種好分割為:([1,2,1], [3]) 和 ([1,2,1,3])。
解題思維:
「沒有任兩個子陣列包含著相同的數字」換句話說就是同一種數字要在同一個子陣列中。
因此我們可以先把每一種數字橫跨的索引值區間找出來。可以用雜湊表(Hash Table),也可以單純地連同原本的索引值複製一份 nums,然後先按排序數值大小、再按索引值大小排序。這樣一來,同樣的數字會排在一起。並且一群數字最左側和最右側的那兩個數字之原始索引值即是橫跨的區間。
接著觀察兩種數字的區間 [a, b] 和 [c, d]。如果 [a, b] 和 [c, d] 之間沒有交集——即 b < c 或 d < a,則單論這兩種數字的話,它們可以選擇分在同一個子陣列,也可以選擇分開成兩個子陣列;反之,則兩區間有重疊,因此必定得是同一個子陣列。
所以可以看到每當有兩種數字區間有所重疊時,該兩區間應合併成一個。重複此步驟直到沒有任何區間可以合併為止。
假設最後剩 C 個區間,則答案即為 2 ^ (C - 1),因為每兩個相鄰的區間可以選擇「要」或「不要」分在同一個子陣列。可以看到 C 不會超過 nums.length,所以不一定要使用快速冪(參見
這題)求得。可以直接慢慢乘上去。
而要求得 C 之值,即可以參見
這題。精神基本上一樣,只是現在不是求區間覆蓋長度。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。