• [LeetCode] 659. Split Array into Consecutive Subsequences


    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

    分割数组为连续子序列。

    给你一个按升序排序的整数数组 num(可能包含重复数字),请你将它们分割成一个或多个子序列,其中每个子序列都由连续整数组成且长度至少为 3 。

    如果可以完成上述分割,则返回 true ;否则,返回 false 。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/split-array-into-consecutive-subsequences
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    这道题有两种思路,一种是贪心,一种涉及到最小堆。我这里暂时提供一个最小堆的做法。类似题目有846和1296。

    题目的目标是需要凑若干个长度起码为3的连续整数子数组,所以我们一开始肯定是要遍历input里的每个数字,并且用hashmap<num, pq>为每个unique的数字创建一个最小堆,意思是记录每个以 num 为结尾的子数组的个数。最小堆里面放的是以num为结尾的子数组的长度,所以长度最短的子数组在堆顶。

    开始遍历 input 数组,当遇到一个数字 num 的时候,放入hashmap,同时去看一下hashmap里面是否有 num - 1,如果有,需要计算一下以 num - 1 为结尾的子数组的长度是多少,这样 num 才能被叠加到这个长度上去。如果这个 num 能被叠加,则需要去hashmap里对 num - 1 的value--,直到去掉这个key为止。如果 num - 1 不存在,则说明当前的 num 应该是一个子数组的起点,则直接把他放入hashmap即可。

    在遍历完所有元素之后,我们再次遍历hashmap的keyset,如果其中有任何一个key的堆顶元素小于3,则说明存在以某个数字为结尾的子数组,其长度不足3,这不符合题意,返回false。

    时间O(nlogn) - 其中O(n)是遍历每个元素,当子数组长度有变化的时候,往pq中加入元素的复杂度是O(logn),所以整体还是O(nlogn)

    空间O(n)

    Java实现

     1 class Solution {
     2     public boolean isPossible(int[] nums) {
     3         // <lastNumber, pq<length>>
     4         // 以num为结尾的子数组的长度
     5         // pq是最小堆,最短的子数组长度在堆顶
     6         HashMap<Integer, PriorityQueue<Integer>> map = new HashMap<>();
     7         for (int num : nums) {
     8             if (!map.containsKey(num)) {
     9                 map.put(num, new PriorityQueue<>());
    10             }
    11             if (map.containsKey(num - 1)) {
    12                 int prevLength = map.get(num - 1).poll();
    13                 if (map.get(num - 1).isEmpty()) {
    14                     map.remove(num - 1);
    15                 }
    16                 map.get(num).offer(prevLength + 1);
    17             } else {
    18                 map.get(num).offer(1);
    19             }
    20         }
    21 
    22         for (Integer key : map.keySet()) {
    23             if (map.get(key).peek() < 3) {
    24                 return false;
    25             }
    26         }
    27         return true;
    28     }
    29 }

    相关题目

    659. Split Array into Consecutive Subsequences

    846. Hand of Straights

    1296. Divide Array in Sets of K Consecutive Numbers

    LeetCode 题目总结

  • 相关阅读:
    Post请求的两种编码格式:application/x-www-form-urlencoded和multipart/form-data传参方式
    工作中常用的JavaScript函数片段
    解决导入导出Excel表格文字乱码问题
    清空antd-design时间选择组件 RangePicker的值
    react.js Hooks路由跳转
    linux跳板机服务器搭建
    docker及docker-compose学习
    Android Jenkins+Git+Gradle持续集成
    Windows Server 2008 R2常规安全设置及基本安全策略
    ubuntu lnmp安装及php扩展
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14085065.html
Copyright © 2020-2023  润新知