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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机专业英语复试专业问题(计算机专业笔试题)

    总述前段时间准备计算机考研复试,发现大部分的学校需要面试英语口语,但是我就一直很疑惑,老师们会怎样进行问答。通过在网上查阅和自我总结,特地将我找到的资料分享给小伙伴。祝愿所有小伙伴能考研成功。问题分类所有的问题大概会分为以下几类:一、自我介绍1、英文自我介绍2、中文自我介绍二、自我认知1、兴趣2、家庭3、优点缺点三、实践经历1、实践经历2、科研经历3、工作经历四、本校学校1、本科学校2、毕业论文五…

    2022年4月16日
    48
  • oracle索引视图_位图联合索引

    oracle索引视图_位图联合索引一.什么是位图索引我们目前大量使用的索引一般主要是B*Tree索引,在索引结构中存储着键值和键值的RowID,并且是一一对应的.而位图索引主要针对大量相同值的列而创建(例如:类别,操作员,部门ID,库房ID等),索引块的一个索引行中存储键值和起止Rowid,以及这些键值的位置编码,位置编码中的每一位表示键值对应的数据行的有无.一个位图索引块可能指向的是几十甚至成百上千行数据的位置.这种方式存储数据…

    2025年7月17日
    0
  • dispatch_once认识分析

    dispatch_once认识分析

    2022年1月5日
    42
  • delete、truncate、drop的区别有哪些,该如何选择

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 来源:blog.csdn.net/qq_39390545/article/details/107144859 上周同…

    2021年6月26日
    87
  • windows 强制删除文件夹 不提示确认

    windows 强制删除文件夹 不提示确认rd/s/qE:\apache-tomcat-6.0.41\apache-tomcat-6.0.41\webapps\concrete-platform-web

    2022年6月3日
    42
  • 互联网创业公司如何防御ddos攻击风险_怎么防止ddos

    互联网创业公司如何防御ddos攻击风险_怎么防止ddosDDoS(DistributedDenialofService,分布式拒绝服务)主要通过大量合法的请求占用大量网络资源,从而使合法用户无法得到服务的响应,是目前最强大、最难防御的攻击之一。什么是DDoS攻击?看到一个好玩的解释,源自百度百科,一群恶霸试图让对面那家有着竞争关系的商铺无法正常营业,他们会采取什么手段呢?恶霸们扮作普通客户一直拥挤在对手的商铺,赖着不走,真正的购物者却无法进入;或者总是和营业员有一搭没一搭的东扯西扯,让工作人员不能正常服务客户;也可以为商铺的经营者提供虚假信息,商铺

    2025年6月3日
    0

发表回复

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

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