題目連結:
題目意譯:
你被給定一個索引值從 0 開始整數陣列 nums。你必須將該陣列分拆成一個或多個連續子陣列。
如果每一個得到的子陣列都符合以下條件之一,則我們稱呼該分拆是合法的:
子陣列由恰好兩個相等的元素組成。例如,子陣列 [2,2] 是符合的、
子陣列由恰好三個相等的元素組成。例如,子陣列 [4,4,4] 是符合的、
子陣列由恰好三個連續遞增的元素組成,也就是說相鄰元素之差為 1。例如,子陣列 [3,4,5] 是符合的,但 [1,3,5] 則不是。
如果該陣列有至少一個合法分拆方式,則回傳真(True);反之,回傳假(False)。
限制:
2 ≦ nums.length ≦ 10 ^ 5
1 ≦ nums[i] ≦ 10 ^ 6
範例測資:
範例 1:
輸入: nums = [4,4,4,5,6]
輸出: true
解釋: 該陣列可以被分拆成子陣列 [4,4] 和 [4,5,6]。
該分拆是合法的,所以我們回傳真。
範例 2:
輸入: nums = [1,1,1,2]
輸出: false
解釋: 這個陣列沒有合法的分拆方式。
解題思維:
典型的動態規劃(Dynamic Programming,DP)之題型。
定義一陣列 D,其中 D[i] 代表著 nums 中前 i 個元素所組成的子陣列本身是否有合法的分拆方式(D[i] == false 代表沒有;反之 D[i] == true 則代表有)。而遞迴式為:
D[0] = true(為了方便,假設空陣列有合法分拆方式)、
D[1] = false、
D[2] = true,如果 nums[0] == nums[1]、
D[2] = false,如果 nums[0] != nums[1]、
(注:這邊把 D[2] 額外列出來是因為等下寫起來比較單純)
D[i] = (nums[i - 1] == nums[i - 2] && D[i - 2]) ||
(nums[i - 1] == nums[i - 2] && nums[i - 2] == nums[i - 3] && D[i - 3]) ||
(nums[i - 1] == nums[i - 2] + 1 && nums[i - 2] == nums[i - 3] + 1 && D[i - 3]),
其中 2 < i ≦ nums.length。
(注:看起來很複雜,但只是題目判斷子陣列符不符合的條件而已。)
其中「&&」代表邏輯運算「和」(AND)而「||」代表邏輯運算「或」(OR)。
因此我們從 D[3] 開始一路根據以上條件求到 D[nums.length] 為止,此時 D[nums.length] 即為所求。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。