博客
关于我
分割数组为连续子序列
阅读量:572 次
发布时间:2019-03-10

本文共 5860 字,大约阅读时间需要 19 分钟。

给你一个按升序排序的整数数组 num(可能包含重复数字),请你将它们分割成一个或多个子序列,其中每个子序列都由连续整数组成且长度至少为 3 。如果可以完成上述分割,则返回 true ;否则,返回 false 。 示例 1:输入: [1,2,3,3,4,5]输出: True解释:你可以分割出这样两个连续子序列 : 1, 2, 33, 4, 5来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/split-array-into-consecutive-subsequences著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

文章目录

1. 解题思路

因为有最小长度限制 所以尽量减少队列的数目 让队列变得更长

每新计算一个数 从已有的队列中最短的开始 判断是否满足条件(队列最后一个元素+1等于当前值) 如果满足填入 若不满足 新建一个队列

最终判断是否每个队列的数组都大于等于3

2. 初始版本代码(超时)

public class LianshuZixulie {          public boolean isPossible(int[] nums) {           if (nums.length < 3) {               return false;        }        List
> result = new ArrayList<>(); result.add(new ArrayList<>()); result.get(0).add(nums[0]); for (int i = 1; i < nums.length; i++) { int j = 0; for (; j < result.size(); j++) { int last = result.get(j).get(result.get(j).size() - 1); if (nums[i] == last + 1) { result.get(j).add(nums[i]); break; } } if (j >= result.size()) { List
temp = new ArrayList<>(); temp.add(nums[i]); result.add(temp); } Collections.sort(result, Comparator.comparingInt(List::size)); } for (List
tmp: result) { if (tmp.size() < 3) { return false; } } return true; } public static void main(String[] args) { int [] input = new int[] { 1,2,3,3,4,4,5,5}; System.out.println(new LianshuZixulie().isPossible(input)); }}

3. 优化排序(超时)

超出时间限制 对排序部分优化一下 去除不必要的操作

public class LianshuZixulie {       /**     * 从已存在的队列中找一个最短的可填的进去     * 找不到则新建一个队列     */    public boolean isPossible(int[] nums) {           if (nums.length < 3) {               return false;        }        List
> result = new ArrayList<>(); result.add(new ArrayList<>()); result.get(0).add(nums[0]); for (int i = 1; i < nums.length; i++) { int j = 0; for (; j < result.size(); j++) { int last = result.get(j).get(result.get(j).size() - 1); if (nums[i] == last + 1) { result.get(j).add(nums[i]); // 从当前位置向后调整 adjustNext(result, j); break; } } if (j >= result.size()) { List
temp = new ArrayList<>(); temp.add(nums[i]); // 直接插入头部 result.add(0, temp); } //Collections.sort(result, Comparator.comparingInt(List::size)); } return result.get(0).size() >= 3; } private void adjustNext(List
> result, int i) { for (int j = i + 1; j < result.size(); j++) { if (result.get(j - 1).size() > result.get(j).size()) { Collections.swap(result, j-1, j); } } } public static void main(String[] args) { int [] input = new int[] { 1,2,3,3,4,4,5,5}; System.out.println(new LianshuZixulie().isPossible(input)); }}

4. 最终版本

仍然超时,需要减少一下swap的次数(数组实现的列表 swap耗时较大)

改造一下adjustNext 函数

private void adjustNext(List
> result, int i) { int j; // 减少操作交换的次数 以及每次swap的范围 for (j = i + 1; j < result.size(); j++) { if (result.get(j).size() >= result.get(i).size()) { Collections.swap(result, i, j-1); break; } } // 如果没有发生交换 if (j >= result.size()) { List
temp = result.get(i); for (int k = i; k < result.size() -1; k++) { result.set(k, result.get(k + 1)); } result.set(result.size() -1, temp); } }

通过, 最终代码

import java.util.ArrayList;import java.util.Collections;import java.util.LinkedList;import java.util.List;/** * https://leetcode-cn.com/problems/split-array-into-consecutive-subsequences/ */public class LianshuZixulie {       /**     * 从已存在的队列中找一个最短的可填的进去     * 找不到则新建一个队列     */    public boolean isPossible(int[] nums) {           if (nums.length < 3) {               return false;        }        List
> result = new ArrayList<>(); result.add(new ArrayList<>()); result.get(0).add(nums[0]); for (int i = 1; i < nums.length; i++) { int j = 0; for (; j < result.size(); j++) { List
curr = result.get(j); int last = curr.get(curr.size() - 1); if (nums[i] == last + 1) { result.get(j).add(nums[i]); // 从当前位置向后调整 adjustNext(result, j); break; } } if (j >= result.size()) { List
temp = new ArrayList<>(); temp.add(nums[i]); // 直接插入头部 result.add(0, temp); } //Collections.sort(result, Comparator.comparingInt(List::size)); } return result.get(0).size() >= 3; } private void adjustNext(List
> result, int i) { int j; // 减少操作交换的次数 for (j = i + 1; j < result.size(); j++) { if ((result.get(j).size() >= result.get(i).size()) && j-1 != i) { Collections.swap(result, i, j-1); break; } } if (result.get(i).size() > result.get(result.size() -1).size()) { List
temp = result.get(i); for (int k = i; k < result.size() -1; k++) { result.set(k, result.get(k + 1)); } result.set(result.size() -1, temp); } } public static void main(String[] args) { int [] input = new int[] { 1,2,3,3,4,4,5,5}; System.out.println(new LianshuZixulie().isPossible(input)); }}
你可能感兴趣的文章
Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
查看>>
NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
查看>>
NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_处理器介绍_处理过程说明---大数据之Nifi工作笔记0019
查看>>
NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_实际操作---大数据之Nifi工作笔记0020
查看>>
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_实际操作_02---大数据之Nifi工作笔记0032
查看>>
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_操作方法说明_01_EvaluteJsonPath处理器---大数据之Nifi工作笔记0031
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka消费者处理器_来消费kafka数据---大数据之Nifi工作笔记0037
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka生产者---大数据之Nifi工作笔记0036
查看>>
NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
查看>>
NIFI大数据进阶_NIFI监控功能实际操作_Summary查看系统和处理器运行情况_viewDataProvenance查看_---大数据之Nifi工作笔记0026
查看>>
NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
查看>>
NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>
NIFI大数据进阶_使用NIFI表达式语言_来获取自定义属性中的数据_NIFI表达式使用体验---大数据之Nifi工作笔记0024
查看>>
NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
查看>>
NIFI大数据进阶_内嵌ZK模式集群2_实际操作搭建NIFI内嵌模式集群---大数据之Nifi工作笔记0016
查看>>
NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
查看>>
NIFI大数据进阶_实时同步MySql的数据到Hive中去_可增量同步_实时监控MySql数据库变化_操作方法说明_01---大数据之Nifi工作笔记0033
查看>>
NIFI大数据进阶_实时同步MySql的数据到Hive中去_可增量同步_实时监控MySql数据库变化_操作方法说明_02---大数据之Nifi工作笔记0034
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_01_实际操作---大数据之Nifi工作笔记0029
查看>>