LeetCode659. 分割数组为连续子序列

659. Split Array into Consecutive Subsequences

[Medium] Given an array nums sorted in ascending order, return true if and only if you can split it into 1 or more subsequences such that each subsequence consists of consecutive integers and has length at least 3.

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

Constraints:

  • 1 <= nums.length <= 10000

题目:输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数。返回你是否能做出这样的分割?

思路:优先队列,参考Link。因为数组是有序的,因此总共有3种情况:

  • num=pre_num。创建一个新的区间。
  • num=pre_num+1。和前一个数合并区间。
  • num>pre_num+1。丢弃以前已有的区间,如果其中某个区间长度小于3,则返回false;同时创建新区间。

对于区间[start, end]end大的优先级高,如果end相同,则长度小的优先级高。

工程代码下载 Github

class Solution {
public:
    bool isPossible(vector<int>& nums) {
        auto cmp = [](Interval a, Interval b) {
            if (a.end == b.end)
                return a.length > b.length;
            return a.end > b.end;
        };
        priority_queue<Interval, vector<Interval>, decltype(cmp)> pq(cmp);
        for (int num : nums){
            while (!pq.empty() && num > pq.top().end + 1) {
                if (pq.top().length < 3)
                    return false;
                pq.pop();
            }

            if(pq.empty() || num == pq.top().end)
                pq.push(Interval(num, num));
            else {  // num == pq.top().end + 1
                int start = pq.top().start;
                pq.pop();
                pq.push(Interval(start, num));
            }
        }

        while (!pq.empty()) {
            if (pq.top().length < 3)
                return false;
            pq.pop();
        }

        return true;
    }
private:
    class Interval {
    public:
        int start;
        int end;
        int length;
        Interval(int start, int end) :start(start), end(end) {
            length = end - start + 1;
        }
    };
};


How to intuitively understand larger than/less than operator in comparator of C++ priority queue container

Priority queue returns the top element based on the comparison operator, meaning that when you retrieve items one by one, you get them in descending order.

The meaning of the comparison operator always stays “less than”, meaning that when compare(A, B) is true, B has higher priority than A, and would be returned earlier from the priority queue.

Inverting the comparison function inverts the order in which you get the items from your priority queue. Specifically, using > in place of < reverses the order to ascending.

你可能感兴趣的:(leetcode)