leetcode 659. Split Array into Consecutive Subsequences
You are given an integer array sorted in ascending order (may contain duplicates), you need to split them into several subsequences, where each subsequences consist of at least 3 consecutive integers. Return whether you can make such a split.
Example 1:
Input: [1,2,3,3,4,5] Output: True Explanation: You can split them into two consecutive subsequences : 1, 2, 3 3, 4, 5
Example 2:
Input: [1,2,3,3,4,4,5,5] Output: True Explanation: You can split them into two consecutive subsequences : 1, 2, 3, 4, 5 3, 4, 5
Example 3:
Input: [1,2,3,4,4,5] Output: False
Note:
- The length of the input is in range of [1, 10000]
題目分類應屬於 模擬。
題目大意,將一升序的數組,分割多個成長度大於等於3的連續的序列,問能不能分割成功。
開始的想法是,第一遍掃一下,依次枚舉3個連續的數作為一個分割,並記錄每個分割最後的一個數(為後期拓展所用)。
第二次掃描,看剩下的數能不能放到任何一個分割的後面。如果能,那麽更新分割的最後一個值。
第三次掃描,看還有沒有剩下的數字,如果沒有那麽返回true,否則false
看似天一無縫,卻始終過不了倒數第二個測試例子------> 179 / 180 test cases passed.
手寫了一個樣例 [1,2,3,4,5,5,5,6,6,7,7,8,9,10]
在處理的時候,按照上上面的套路(1,2,3)(4,5,6),(5,6,7),(7,8,9) 剩下 5和10, 5,和10 只能放在 3,6,7,9後面,10可以放在9後面,但是5沒有地方放,返回false。
可是 我們肉眼能找到(1,2,3,4,5)(5,6,7)(5,6,7)(8,9,10)這樣合法的分割,應該返回true。思路有瑕疵。其實我們思考的順序有錯誤,對於當前的數字x,我們應該先判斷x-1是否存在,如果存在就直接放上就好了,不存在的時候再構建一個長度為3個分割,如果長度為3的分割都構建不了,那麽直接返回false就ok了。說道這裏,這題目還是有貪心的味道的....
這裏mp2[y]記錄以y作為i分割末尾的數量。
class Solution { public: bool isPossible(vector<int>& nums) { int n = nums.size(); //sort(nums.begin(), nums.end()); if (n < 3) return false; map<int, int>mp; for (int i = 0; i < n; ++i) mp[nums[i]]++; map<int, int>mp2; for (int i = 0; i < n; ++i) { int x = nums[i]; if (mp[x] <= 0) continue; if (mp2[x-1] > 0) { mp2[x]++, mp2[x-1]--, mp[x]--; } else if (mp[x+1] > 0 && mp[x+2] > 0) { mp[x]--, mp[x+1]--, mp[x+2]--; mp2[x+2]++; } else { return false; } } return true; } };
leetcode 659. Split Array into Consecutive Subsequences