LeetCode[659]Split Array into Consecutive Subsequences(Java)

Description:

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]

Topic:
Heap(堆) Greedy(贪婪)

Heap:

       堆栈是一种执行“后进先出”算法的数据结构。

       堆栈就是这样一种数据结构。它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——push”)这个区域之中。有一个地址指针总指向最后一个压入堆栈的数据所在的数据单元,存放这个地址指针的寄存器就叫做堆栈指示器。开始放入数据的单元叫做“栈底”。数据一个一个地存入,这个过程叫做“压栈”。在压栈的过程中,每有一个数据压入堆栈,就放在和前一个单元相连的后面一个单元中,堆栈指示器中的地址自动加1。读取这些数据时,按照堆栈指示器中的地址读取数据,堆栈指示器中的地址数自动减 1。这个过程叫做“弹出pop”。如此就实现了后进先出的原则。

二叉堆能很好的实现优列的基本操作。在二叉堆的每个数中,每个元素都要保大于等于另两个特定位置的元素。

堆的性

       当一二叉的每个点都大于等于(大堆)或小于等于(小堆)它的两个子,被称堆有序。

       堆是一完全二叉

PriorityQueue优先队列

PriorityQueue底层实现的数据结构是堆。

而优先队列在Java中的使用的最小堆,意味着每次从队列取出的都是最小的元素

Greedy贪心:

在对问题求解时,总是做出在当前看来是最好的选择。不从整体最优上加以考虑,所做出的是在某种意义上的局部最优解。


Solution:

创建HashMap存储键值对(队列的最末元素,队列的长度)

class Solution {
    HashMap<Integer, PriorityQueue<Integer>> map = new HashMap<Integer, PriorityQueue<Integer>>();
    public boolean isPossible(int[] nums) {
        for(int num : nums){
            PriorityQueue<Integer> last = helper(num - 1);
            int len = last.isEmpty()? 0 : last.poll();
            PriorityQueue<Integer> current = helper(num);
            current.offer(len + 1);
        }
        for(int key : map.keySet()){
            for(int len : map.get(key)){
                if(len < 3){
                    return false;
                }
            }
        }
        return true;
    }
    public PriorityQueue<Integer> helper(int num){
        PriorityQueue<Integer> temp = map.get(num);
        if(temp == null){
            temp = new PriorityQueue<Integer>();
            map.put(num, temp);
        }
        return temp;
    }
}

首先判断以(num-1)为结尾的序列是否存在,

如果存在,获取长度最小值len并出栈,创建以num为结尾的数组,并设置长度为len + 1,推入优先队列;

如果不存在,创建新的序列,以num为结尾,并且长度为1,推入优先队列,创建新的键值对(num,currentPriorityQueue)推入map中。

1,2,3,3,4,4,5,5

numlastlencurrentmap
1null->(0,[ ])0(1, [1])(0,[ ] ) (1, [1])
2(1, [1])1(2, [2])(0,[ ] ) (1, [ ])(2, [2])
3(2, [2])2(3, [3])(0,[ ] ) (1, [ ])(2, [ ])(3, [3])
3(2, [ ])0(3, [1])(0,[ ] ) (1, [ ])(2, [ ])(3, [3])(3, [1])
4(3, [1])1(4, [2])(0,[ ] ) (1, [ ])(2, [ ])(3, [3])(3, [ ])(4, [2])
4(3, [3])3(4, [4])(0,[ ] ) (1, [ ])(2, [ ])(3, [ ])(3, [ ])(4, [2])(4, [4])
5(4, [2])2(5, [3])(0,[ ] ) (1, [ ])(2, [ ])(3, [ ])(3, [ ])(4, [ ])(4, [4])(5, [3])
5(4, [4])4(5, [5])(0,[ ] ) (1, [ ])(2, [ ])(3, [ ])(3, [ ])(4, [ ])(4, [ ])(5, [3])(5, [5])

Code:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值