[LeetCode] 贪心算法之 Split Array into Consecutive Subsequence

题目

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

分析

这题的思路有多种,O( n2 )的就不在考虑范围内了,主要考虑如何降到O( nlogn )甚至O( n )。这题的思路中有个问题,就在于你是要优先扩展subsequence的数量,还是长度的问题。实际上是需要尽量保证长度的,不然有些example会存在优先数量不能过,但是优先长度能过的情况。
思路上就是对于每个num,检查目前每个已存在的subsequence有没有最大值为num-1的这种序列,如果有就加入这个序列。否则,就检查还没有被放进subsequence的值中有没有num+1和num+2,如果有一个没有,那么就直接返回false。

时间复杂度分析

需要扫描array两遍,采用hash方法存储,插入删除是常数时间(如果采用unordered_multiset可能只用扫描一遍,直接构造函数添加进去),总的时间复杂度是O( n )。

代码

class Solution {
public:
    bool isPossible(vector<int>& nums) {
        // count is used to keep the frequence of each num
        // subsequence is mapped from the max number of each subsequence to 
        // its correlated frequency
        unordered_map<int,int> count, subsequence;
        for (int i : nums) count[i]++;
        for (int i : nums){
            if (!count[i]) continue;
            count[i]--;
            // condition that if having a subsequence with max num is i-1
            if (subsequence[i - 1] > 0) {
                subsequence[i - 1]--;
                subsequence[i]++;
            }
            // condition that start a new subsequence
            else if (count[i + 1] && count[i + 2]){ 
                count[i + 1]--;
                count[i + 2]--;
                subsequence[i + 2]++;
            }
            else return false;
        }
        return true;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_34035179/article/details/78252818
今日推荐