[LeetCode] 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:

  1. The length of the input is in range of [1, 10000]

博主第一眼看到这题,心想,我去,这不就是打牌么,什么挖坑,拐3,红桃4啊,3个起连,有时候排组合的好,就不用划单儿。这道题让我们将数组分割成多个连续递增的子序列,注意这里可能会产生歧义,实际上应该是分割成一个或多个连续递增的子序列,因为[1,2,3,4,5]也是正确的解。这道题就用贪婪解法就可以了,我们使用两个哈希表map,第一个map用来建立数字和其出现次数之间的映射freq,第二个用来建立可以加在某个连续子序列后的数字及其可以出现的次数之间的映射need。对于第二个map,举个例子来说,就是假如有个连,[1,2,3],那么后面可以加上4,所以就建立4的映射。这样我们首先遍历一遍数组,统计每个数字出现的频率,然后我们开始遍历数组,对于每个遍历到的数字,首先看其当前出现的次数,如果为0,则继续循环;如果need中存在这个数字的非0映射,那么表示当前的数字可以加到某个连的末尾,我们将当前数字的映射值自减1,然后将下一个连续数字的映射值加1,因为当[1,2,3]连上4后变成[1,2,3,4]之后,就可以连上5了;如果不能连到其他子序列后面,我们来看其是否可以成为新的子序列的起点,可以通过看后面两个数字的映射值是否大于0,都大于0的话,说明可以组成3连儿,于是将后面两个数字的映射值都自减1,还有由于组成了3连儿,在need中将末尾的下一位数字的映射值自增1;如果上面情况都不满足,说明该数字是单牌,只能划单儿,直接返回false。最后别忘了将当前数字的freq映射值自减1。退出for循环后返回true,参见代码如下: 

public:
    bool isPossible(vector<int>& nums) {
        unordered_map<int, int> freq, need;
        for (int num : nums) ++freq[num];
        for (int num : nums) {
            if (freq[num] == 0) continue;
            else if (need[num] > 0) {
                --need[num];
                ++need[num + 1];
            } else if (freq[num + 1] > 0 && freq[num + 2] > 0) {
                --freq[num + 1];
                --freq[num + 2];
                ++need[num + 3];
            } else return false;
            --freq[num];
        }
        return true;
    }
};

 参考资料:

https://discuss.leetcode.com/topic/99187/java-o-n-time-o-n-space

本文转自博客园Grandyang的博客,原文链接:[LeetCode] Split Array into Consecutive Subsequences 将数组分割成连续子序列

,如需转载请自行联系原博主。

相关文章
|
1月前
|
存储 算法
《LeetCode》—— 摆动序列
《LeetCode》—— 摆动序列
|
1月前
|
算法
【数组相关面试题】LeetCode试题
【数组相关面试题】LeetCode试题
|
1月前
|
存储
力扣面试经典题之数组/字符串
力扣面试经典题之数组/字符串
21 0
|
8天前
|
C++
【力扣】2562. 找出数组的串联值
【力扣】2562. 找出数组的串联值
|
1月前
|
存储 算法
《LeetCode 热题 HOT 100》——寻找两个正序数组的中位数
《LeetCode 热题 HOT 100》——寻找两个正序数组的中位数
|
1月前
|
存储
力扣刷题-最大子数组和
力扣刷题-最大子数组和
10 1
|
1月前
leetcode2967. 使数组成为等数数组的最小代价
leetcode2967. 使数组成为等数数组的最小代价
20 0
|
1月前
|
算法 搜索推荐
LeetCode刷题---215. 数组中的第K个最大元素(双指针,快速选择)
LeetCode刷题---215. 数组中的第K个最大元素(双指针,快速选择)
|
1月前
|
Go C++
【力扣】2645. 构造有效字符串的最小插入数(动态规划 贪心 滚动数组优化 C++ Go)
【2月更文挑战第17天】2645. 构造有效字符串的最小插入数(动态规划 贪心 滚动数组优化 C++ Go)
31 8
|
1月前
|
算法 测试技术 索引
力扣面试经典题之数组/字符串(二)
力扣面试经典题之数组/字符串(二)
13 0

热门文章

最新文章