Java 最长递增子序列_最长递增子序列问题 Java

Java 最长递增子序列_最长递增子序列问题 Java最长递增子序列问题LIS(longestincreasingsubsequence)例如给定一个数列,长度为N,求这个数列的最长上升(递增)子数列(LIS)的长度.以1,7,2,8,3,4为例。这个数列的最长递增子数列是1234,长度为4;次长的长度为3,包括178;123等.设数组为:arr设foo(k)为:以数列中第k项(为了与java数组逻辑…

大家好,又见面了,我是你们的朋友全栈君。

最长递增子序列问题 LIS(longest increasing subsequence) 例如

给定一个数列,长度为N,

求这个数列的最长上升(递增)子数列(LIS)的长度.

1, 7, 2, 8, 3, 4

为例。

这个数列的最长递增子数列是 1 2 3 4,长度为4;

次长的长度为3, 包括 1 7 8; 1 2 3 等.

设数组为:arr

设 foo(k) 为:以数列中第k项 (为了与java数组逻辑一致,这里的k从0开始计算) 结尾的最长递增子序列的长度

则:

foo(0) == 1

foo(k) == max(arr[k]>arr[0]?foo(0)+1:foo(0),

arr[k]>arr[1]?foo(1)+1:foo(1) ,

… ,

arr[k]>arr[k-1]?foo(k-1)+1:foo(k-1))

java代码

public class LISDemo {

public static void main(String[] args){

int[] arr = new int[10];

Random random = new Random();

for (int i = 0; i < arr.length; i++) {

arr[i] = random.nextInt(100);

}

System.out.println(“数组”+Arrays.toString(arr));

long time = System.currentTimeMillis();

System.out.println(“结果: “+foo(arr, arr.length-1));

System.out.println(“耗时: “+(System.currentTimeMillis()-time));

}

private static int foo(int[] arr,int end){

if (end==0) {

return 1;

}

int len = 0;

for (int i = 0; i < end; i++) {

int temp = foo(arr,i);

len = Math.max(len,arr[end]>arr[i]?temp+1:temp);

}

return len;

}

}

这段代码能计算出正确的结果,但是存在问题:

要计算 foo(n)必须先得到 foo(0)~foo(n-1)的值

要计算 foo(n-1)必须先得到 foo(0)~foo(n-2)的值

以此类推,可以把他画成一颗多叉树,时间复杂度达到O(2^n)

运行这段代码就会发现 每当数组长度+1 运行耗时大致翻倍,数组长度为几十的时候,运行时间已经无法容忍的长了。

以foo(3)为例,可以画成下面这棵树

f89dbd0539d4

可以发现,相同参数的方法被重复计算了多遍,我们可以建立一个hashmap把参数和对应的值存入其中,当结果已经计算过,就直接从hashmap中取出结果不再计算,修改代码为如下,保留了原来的方法做个对比,执行效率天差地别:

public class LISDemo {

public static void main(String[] args){

int[] arr = new int[31];

Random random = new Random();

for (int i = 0; i < arr.length; i++) {

arr[i] = random.nextInt(100);

}

System.out.println(“数组”+Arrays.toString(arr));

LIS lis = new LIS(arr);

long time = System.currentTimeMillis();

System.out.println(“结果1: “+lis.foo());

System.out.println(“耗时1: “+(System.currentTimeMillis()-time));

time = System.currentTimeMillis();

System.out.println(“结果2: “+foo(arr, arr.length-1));

System.out.println(“耗时2: “+(System.currentTimeMillis()-time));

}

// 最长递增子序列 longest increasing subsequence

private static class LIS{

int[] arr;

HashMap values = new HashMap<>();

LIS(int[]arr){

this.arr = arr;

}

int foo(){

return foo(arr,arr.length-1);

}

private int foo(int[] arr,int end){

Integer value = values.get(end);

if (value != null) {

return value;

}

if (end==0) {

values.put(0,1);

return 1;

}

int len = 0;

for (int i = 0; i < end; i++) {

int temp = foo(arr,i);

len = Math.max(len,arr[end]>arr[i]?temp+1:temp);

}

values.put(end,len);

return len;

}

}

private static int foo(int[] arr,int end){

if (end==0) {

return 1;

}

int len = 0;

for (int i = 0; i < end; i++) {

int temp = foo(arr,i);

len = Math.max(len,arr[end]>arr[i]?temp+1:temp);

}

return len;

}

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132492.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • javascript按位异或(^)[通俗易懂]

    javascript按位异或(^)[通俗易懂]varnum1=25;varnum2=3;alert(num1^num2);//输出:26;对两个数值的二进制写法进行比较,只有当相同位置上的数字只有一个1时,才返回1,有两个1或者都是0则返回0,然后转换成十进制数值;

    2022年6月5日
    34
  • 数据解读 | 川菜出圈只靠辣?你太小瞧川菜了[通俗易懂]

    数据解读 | 川菜出圈只靠辣?你太小瞧川菜了[通俗易懂]图片来自网络,侵删作者|钟黛编辑|陆泓设计|张梓豪来源|DT财经(ID:DTcaijing)聚餐不知道吃什么,结局通常是二选一…

    2022年5月24日
    32
  • Java视屏教程下载地址——孙鑫讲解

    Java视屏教程下载地址——孙鑫讲解CD1-2        CD3-4CD5-6CD7-8CD9-10JLesson7CD11-12光盘讲解:CD1:Java的一些基本概念,Java的起源、为什么我们要学习Java语言,Java跨平台原理剖析;Java环境变量的配置,初学者常犯的问题,Java语言的基本数据类型和Java的语句。CD2:Java面向对象编程,面向对象编程和面向过程

    2022年5月16日
    38
  • 将二维数组反转

    将二维数组反转题目:实现如下转换$arr=[[1,2,3],[4,5,6],[7,8,9]];转换后$arr1=[[7,4,1],[8,5,2],[9,6,3]];转换代码如下:functiontransfer($arr){$res=[];foreach($…

    2022年5月9日
    32
  • 服务器磁盘配置信息,服务器磁盘阵列配置

    服务器磁盘配置信息,服务器磁盘阵列配置说到磁盘阵列(RAID,RedundantArrayofIndependentDisks),现在几乎成了网管员所必须掌握的一门技术之一,特别是中小型企业,因为磁盘阵列应用非常广泛,它是当前数据备份的主要方案之一。然而,许多网管员只是在各种媒体上看到相关的理论知识介绍,却并没有看到一些实际的磁盘阵列配置方法,所以仍只是一知半解,到自己真正配置时,却无从下手。本文要以一个具体的磁盘阵列配置方法…

    2022年6月6日
    49
  • 怎么开发微信公众帐号_建立微信公众号收费吗

    怎么开发微信公众帐号_建立微信公众号收费吗微信公众账号的注册流程(图文详解)

    2022年8月3日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号