Java实现求数组最长子序列算法示例
作者:antchow- 发布时间:2023-09-28 12:35:14
标签:Java,数组,最长子序列,算法
本文实例讲述了Java实现求数组最长子序列算法。分享给大家供大家参考,具体如下:
问题:给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱) 例如:给定一个长度为8的数组A{1,3,5,2,4,6,7,8},则其最长的单调递增子序列为{1,2,4,6,7,8},长度为6。
思路1:第一眼看到题目,很多人肯定第一时间想到的是LCS。先给数组排个序形成新数组,然后再把新数组和原数组拿来求LCS,即可得到答案。这种解法很多人能想得到,所以就不再赘述。
思路2:按照思路1的想法,最后求LCS时还是得用到DP,我们干嘛不直接用DP来求解呢。对于数组arr,我们从后往前遍历数组,分别求出当子序列以arr[i]
结尾时的最长子序列,然后取其中的最大值。即可得到整个数组的最长子序列。 那么怎么求以arr[i]
结尾时的最长子序列呢,这就转换成一个DP问题了。要求arr[i]
的最长子序列,只需要求出arr[i-1]
的最长子序列。即:max{arr[i]}=max{arr[i-1]}+1
。
java实现代码:
public class arrDemo {
public static void main(String[] args) {
// int[] arr = {89, 256, 78, 1, 46, 78, 8};
int[] arr = { 1, 3, 5, 2, 4, 6, 7, 8 };
// int[] arr = {6, 4, 8, 2, 17};
int max = 0;
int maxLen = arr.length;
// 从后往前遍历数组,分别求出以arr[i]结尾的时候的最长子序列长度
for (int i = arr.length - 1; i > 0; i--) {
int[] newArr = new int[i];
System.arraycopy(arr, 0, newArr, 0, i);
int currentLength = 1 + dp(newArr, arr[i]);
if (currentLength > max)
max = currentLength;
// 最长子序列的长度最长为原始数组的长度,
// 因为不需要我们求最长子序列的元素,所以直接结束循环,减少时间开销
if (max == maxLen)
break;
}
System.out.println(max);
}
public static int dp(int[] arr, int end) {
// 递归结束条件
if (arr.length == 1) {
// 小于end则包含在子序列中,子序列长度+1
if (arr[0] <= end)
return 1;
else
return 0;
}
// 遍历数组,找到最靠近end的并且<=end的元素位置i
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] <= end) {
// 从i处截断数组,将arr[0]到arr[i-1]组成新数组继续递归求长度
int[] newArr = new int[i];
System.arraycopy(arr, 0, newArr, 0, i);
// 分别计算包含arr[i]时的最长子序列和不包含arr[i]时的最长子序列,取最大值
int containLen = dp(newArr, arr[i]) + 1;
int notContainLen = dp(newArr, end);
return containLen > notContainLen ? containLen : notContainLen;
}
}
// 如果没找到比end更小的,返回长度为0
return 0;
}
}
运行结果:
6
我的方法由于中间开辟了多个新数组,可能占用的空间有点多,不过我觉得应该也不是很多- -,具体我也没统计过。如果有不对的地方还请指正。
希望本文所述对大家java程序设计有所帮助。
来源:https://blog.csdn.net/ztzy520/article/details/78018321


猜你喜欢
- 一、Fork/Join框架的理解ForkJoinTask类属于java.util.concurrent 包下;ForkJoinTask类下有
- 1. 缓存、两级缓存1.1 内容说明Spring cache:主要包含spring cache定义的接口方法说明和注解中的属性说明sprin
- 0.导入命名空间:using Microsoft.Office.Core;using Microsoft.Office.Interop.Ex
- 最近项目中需要用到IO流来读取图片以提供前台页面展示,由于以前一直是用url路径的方式进行图片展示,一听说要项目要用IO流读取图片感觉好复杂
- 问题今天在springboot中使用mybatis的时候不能字段不能够进行自动映射,mybatis的版本是3.5.11,数据库是按照下划线进
- 本文实例为大家分享了C#实现围棋游戏的具体代码,供大家参考,具体内容如下之所以选择围棋作为大作业一方面是想挑战一下,另一方面是由于从6岁学围
- 异常算术异常类:ArithmeticExecption空指针异常类:NullPointerException类型强制转换异常:ClassCa
- 实现窗口小部件,访问手机储存卡指定目录中的图片文件,然后随机选择一张在窗口的小部件中显示。图片路径使用List存储,适合初级Android学
- 目录1、创建 Android 库2、上传aar包至Maven * 3、其他项目使用4、QA1、创建 Android 库按以下步骤在项目中创建新
- 方法一:实现Comparator接口,并重写compare方法实体类代码:import java.util.Comparator;/** *
- Eclipse提供了一个可扩展插件的开发系统。这就使得Eclipse在运行系统之上可以实现各种功能。这些插件也不同于其他的应用(插件的功能是
- Java中常用关键字:与数据类型相关(10)与流程控制相关(13)if: 表示条件判断,一般用法if(关系表达式),后跟else或
- 1.运行程序时, AddOrEditBook1.BooksType = GetTypeName(model.BookType_ID); 出现
- using System; using System.IO; public class FileApp { &nbs
- 开发过程中,有时候图标稍微大点,比如48×48的时候,文字就会和图标叠加起来,解决方法如下:TabWidget tw = tabHost.g
- 前言虽然从学java的第一个程序——helloworld至今,已经有好几个年头了。当时自己找资料,看视频,学习了java的输入输出流,多线程
- 方向传感器是算法生成的传感器之一,主要借助于磁场传感器的数据。Android系统自带了方向传感器,不过系统5.0之后方法就被废除了(我们还是
- 前言相信很多人对枚举并不陌生,枚举可以很方便和直观的管理一组特定值。如果我们在页面上直接输出我们希望匹配的汉语意思或则其他满足我们需求的语句
- 手机升级到安卓O后,突然发现创建快捷方式的功能失效了,查询一番后发现:安卓O要使用ShortcutManager来创建快捷方式。安卓N及以下
- 博主说:有时候,我们需要对数据库中现有的数据进行大量处理操作(例如表中的某个字段需要全部更新等),如果直接使用select * from t