LeetCode——数组篇:659. 分割数组为连续子序列

Posted 阅尽天涯离恨苦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode——数组篇:659. 分割数组为连续子序列相关的知识,希望对你有一定的参考价值。

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

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

示例 1:

输入: [1,2,3,3,4,5]
输出: True
解释:
你可以分割出这样两个连续子序列 : 
1, 2, 3
3, 4, 5

示例 2:

输入: [1,2,3,3,4,4,5,5]
输出: True
解释:
你可以分割出这样两个连续子序列 : 
1, 2, 3, 4, 5
3, 4, 5

示例 3:

输入: [1,2,3,4,4,5]
输出: False

提示:

  1. 输入的数组长度范围为 [1, 10000]

************************************************************

问题分析:

  • 采用链表freq保存数组元素对应个数
  • 采用need用来判断当前元素是否能够插入到一个已经构建好的序列末端
 1     public boolean isPossible(int[] nums) {
 2         //数组中每个元素与出现次数的对应关系
 3         Map<Integer, Integer> freq = new HashMap<>();
 4         Map<Integer, Integer> need = new HashMap<>();
 5 
 6         for (int n : nums) freq.put(n, freq.getOrDefault(n, 0) + 1);
 7 
 8         for (int n: nums) {
 9             if (freq.getOrDefault(n, 0) == 0) continue;
10 
11             if (need.getOrDefault(n, 0) > 0){
12                 need.put(n, need.get(n) - 1);
13                 need.put(n + 1, need.getOrDefault(n + 1, 0) + 1);
14             } else if (freq.getOrDefault(n + 1, 0) > 0 && freq.getOrDefault(n + 2, 0) > 0){
15                 freq.put(n +1, freq.get(n + 1) - 1);
16                 freq.put(n + 2, freq.get(n + 2) - 1);
17                 need.put(n + 3, need.getOrDefault(n + 3, 0) + 1);
18             } else return false;
19             freq.put(n, freq.get(n) - 1);
20         }
21 
22         return true;
23     }

参考链接:https://blog.csdn.net/LaputaFallen/article/details/80034863

在测试时,发现有些条件题目没有给出提示,比如所有nums数组中的元素值大小都在±10000以内,所以也可以基于数组的形式完成,并且效率更高!

 1     //测试中发现nums元素值都在正负10000以内
 2     public boolean isPossible(int[] nums) {
 3         int[] counts = new int[20000];
 4         int[] need = new int[20000];
 5 
 6         for (int i = 0; i < nums.length; i ++) {
 7             //将所有负数转为正数
 8             nums[i] += 10000;
 9             counts[nums[i]] ++;
10         }
11 
12         for (int n : nums) {
13             if (counts[n] == 0) continue;
14 
15             if (need[n] > 0){
16                 need[n] --;
17                 need[n + 1] ++;
18             } else if (counts[n + 1] > 0 && counts[n + 2] > 0){
19                 counts[n + 1] --;
20                 counts[n + 2] --;
21                 need[n + 3] ++;
22             } else return false;
23             counts[n] --;
24         }
25         return true;
26     }

 

以上是关于LeetCode——数组篇:659. 分割数组为连续子序列的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode.659. 分割数组为连续子序列

[LeetCode] 659. Split Array into Consecutive Subsequences 将数组分割成连续子序列

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

LeetCode.1013-分割数组为三个和相同的部分

LeetCode 0915. 分割数组

leetcode - 分割数组的最大值