`
shuofenglxy
  • 浏览: 195292 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

LIS 最长递增子序列算法总结

阅读更多

这里包含了三种求得递增子序列的算法。

是以前写的代码,这里就拖过来了。

import java.util.ArrayList;
import java.util.Collections;

public class LIS {
	public static void LIS(int[] L) { // 时间复杂度为O(n^3)

		Long sTime = System.nanoTime();
		int n = L.length;
		int[] A = new int[n];// 用于存放前i个数值中的递增子序列数值个数;
		A[0] = 1;// 以第a1为末元素的最长递增子序列长度为1;
		ArrayList a[] = new ArrayList[L.length];// 存放对应的子序列
		for (int i = 0; i < L.length; i++) {
			a[i] = new ArrayList();
			a[i].add(L[i]);
		}
		for (int i = 1; i < n; i++)// 循环n-1次
		{
			A[i] = 1;
			for (int j = 0; j < i; j++)// 循环i 次
			{
				if (L[j] < L[i] && A[j] > A[i] - 1) {
					A[i] = A[j] + 1;
					while (a[i].size() != 0) {// 最多i次
						a[i].remove(0);
					}
					if (a[j].size() != 0) {
						for (int k = 0; k < a[j].size(); k++)
							// 最多i次
							a[i].add(a[j].get(k));
					}
					a[i].add(L[i]);
				}

			}
		}
		int max = 1, tag = 0; // 找到对应的最长长度和对应的子序列数组链表a[tag]
		for (int i = 0; i < n; i++) {
			if (A[i] > max) {
				max = A[i];
				tag = i;
			}
		}
		System.out.print("LIS最长递增子序列长度为:" + max + "  ");
		System.out.println("LIS最长递增子序列为:");
		// System.out.println(a[tag]);

		Long eTime = System.nanoTime();
		System.out.println("该LIS用时:" + (eTime - sTime) + "纳秒");
	}

	public static void LCSImproveLIS(int[] L) { // 寻找公共子序列法 O(n^2)

		Long sTime = System.nanoTime();
		int n = L.length;
		int[] Temp = new int[n];// 数组B;
		for (int i = 0; i < n; i++)
			Temp[i] = L[i];
		ShellSort(Temp);

		int[][] opt = new int[n + 1][n + 1];
		for (int i = 0; i < n + 1; i++)
			for (int j = 0; j < n + 1; j++)
				opt[i][j] = 0;
		for (int i = n - 1; i >= 0; i--) {
			for (int j = n - 1; j >= 0; j--) {
				if (L[i] == Temp[j])
					opt[i][j] = opt[i + 1][j + 1] + 1;
				else
					opt[i][j] = Math.max(opt[i + 1][j], opt[i][j + 1]);
			}
		}
		System.out.println();
		System.out.print("LCSImproveLIS最长递增子序列长度为:" + opt[0][0] + "  ");
		System.out.println("LCSImproveLIS最长递增子序列为:");
		int i = 0, j = 0;
		while (i < n && j < n) {
			if (L[i] == Temp[j]) {
				// System.out.print(L[i]+",");
				i++;
				j++;
			} else if (opt[i + 1][j] > opt[i][j + 1])
				i++;
			else
				j++;
		}
		System.out.println();
		Long eTime = System.nanoTime();
		System.out.println("该LCSImproveLIS用时:" + (eTime - sTime) + "纳秒");

	}

	public static void ShellSort(int[] x) {

		for (int i = x.length / 2; i > 2; i /= 2) {
			for (int j = 0; j < i; j++)
				insertSort(x, j, i);
		}
		insertSort(x, 0, 1);
	}

	public static void insertSort(int[] x, int start, int incr) {
		int temp;
		for (int i = start + incr; i < x.length; i += incr) {
			for (int j = i; (j >= incr) && (x[j] < x[j - incr]); j -= incr) {
				temp = x[j];
				x[j] = x[j - incr];
				x[j - incr] = temp;
			}
		}
	}

	public static void ImproveLIS(int[] L) { // 性能可以达到O(nlogn)

		Long sTime = System.nanoTime();
		int n = L.length;
		int[] Temp = new int[n + 1];// 数组B;
		Temp[0] = 0; // 取比较最小值0做基准
		Temp[1] = L[0]; // 起始时,起始元素为L[0]

		int ltag, rtag, middle; // 分别为二分查找的上界,下界和中点;
		ArrayList arr = new ArrayList();
		arr.add(Temp[1]);

		int max = 1; // max为最长递增子序列长度 初始化为1;

		int k = 0;

		// 如果arr中的最后一个元素与Temp中最后一个非0元素不一致 则更改arr中的值最多更改N<n个值
		for (int i = 1; i < n; i++) {
			ltag = 0;
			rtag = max;
			while (ltag <= rtag)// 二分查找最末元素小于L[i]的长度最大的最大递增子序列;
			{
				middle = (ltag + rtag) / 2;
				if (Temp[middle] < L[i])
					ltag = middle + 1;
				else
					rtag = middle - 1;
			}

			Temp[ltag] = L[i];// 将长度为p的最大递增子序列的当前最末元素置为ai+1;
			if (ltag == max) {
				k = max - 1;
				// System.out.println((Integer)arr.get(k));
				while ((k >= 0) && ((Integer) arr.get(k) != Temp[k + 1])) {
					arr.set(k, Temp[k + 1]);
					k--;
				}
			}
			if (ltag > max) {
				max++;
				arr.add(Temp[ltag]);
			}

		}
		System.out.print("ImproveLIS最长递增子序列长度为:" + max + "  ");
		System.out.println("ImproveLIS最长递增子序列为:");
		// System.out.println(arr);
		Long eTime = System.nanoTime();
		System.out.println("该ImproveLIS用时:" + (eTime - sTime) + "纳秒");
	}

	public static int[] random(int n) { // 生成n个不同数值的随机数组
		int a[] = new int[n];
		ArrayList arrlist = new ArrayList();
		for (int i = 0; i < a.length; i++)
			arrlist.add(i + 1);

		for (int i = 0; i < a.length; i++) {
			int temp = (int) (Math.random() * arrlist.size());
			int data = (Integer) arrlist.remove(temp);
			a[i] = data;
		}
		return a;
	}

	public static void main(String args[]) {
		int a[], b[], c[], d[];
		d = random(10);
		int n;
		System.out.println("10个随机自然数时");
		for (int i = 0; i < d.length; i++)
			System.out.print(d[i] + "  ");
		System.out.println();

		LIS(d);
		LCSImproveLIS(d);
		ImproveLIS(d);

		System.out.println("1000个随机自然数时");
		a = random(1000);
		LIS(a);
		LCSImproveLIS(a);
		ImproveLIS(a);

		System.out.println("3000个随机自然数时");
		b = random(3000);
		LIS(b);
		LCSImproveLIS(b);
		ImproveLIS(b);

		System.out.println("10000个随机自然数时");
		c = random(10000);
		LIS(c);
		LCSImproveLIS(c);
		ImproveLIS(c);
	}

}
 

 

0
0
分享到:
评论

相关推荐

    最长递增子序列问题

    最长递增子序列(Longest Increasing Subsequence, LIS)问题是计算机科学中的一种经典动态规划问题,广泛应用于算法设计和分析。在给定的整数序列中,我们的目标是找到一个尽可能长的、不降序的子序列。这个子序列...

    动态规划:最长单调递增子序列

    本篇文章将详细介绍如何利用动态规划求解一个经典问题——寻找给定序列中的最长单调递增子序列(Longest Increasing Subsequence, LIS)。 #### 问题描述 假设有一个整数序列 `a1, a2, ..., aN`。如果存在一个序列...

    最长递增子序列 动态规划法.cpp.rar

    最长递增子序列(Longest Increasing Subsequence, LIS)是计算机科学中常见的算法问题,它在数组或序列中寻找一个尽可能长的严格递增子序列。这个问题在多种领域都有应用,比如股票交易策略、生物信息学等。在这个...

    中科大算法导论课程实验 最长递增子序列 报告

    在中科大软件学院开设的算法导论课程实验中,要求学生研究和实现最长递增子序列问题。最长递增子序列(Longest Increasing Subsequence,简称LIS)问题是一个经典的计算机科学问题,其目标是在一个无序的整数序列中...

    中科大算法导论课程实验 最长递增子序列 代码

    在本实验中,我们关注的是“最长递增子序列”(Longest Increasing Subsequence, LIS)这一经典问题,它是算法课程中的一个核心课题,尤其在动态规划的应用上有着重要的地位。中科大软件学院的这个实验旨在让学生...

    最长子序列什么是最长递增子序列呢

    最长递增子序列 (Longest Increasing Subsequence, LIS) 是指在这个序列中找到的一个子序列 \( L_{\text{in}} = \langle a_{k_1}, a_{k_2}, \ldots, a_{k_m} \rangle \),满足以下两个条件: 1. 序列中的下标满足 \...

    最长递增子序列java源码

    在本实验中,我们将探讨如何使用Java编程语言解决“最长递增子序列”(Longest Increasing Subsequence, LIS)的问题。这是一个经典的动态规划问题,在计算机科学和算法设计中具有广泛的应用,例如在股票交易策略、...

    Rust中最长递增子序列算法_rust_代码_下载

    在 Rust 编程语言中,最长递增子序列(Longest Increasing Subsequence,简称 LIS)是一种常见的算法问题,它的目标是找到一个给定序列中,长度最长的严格递增子序列。这种问题在多种场景下都有应用,比如优化决策...

    最长递增子序列多种实现(java)

    最长递增子序列(Longest Increasing Subsequence, LIS)是计算机科学中一种经典的动态规划问题,广泛应用于算法竞赛和实际编程场景。在这个Java实现中,我们将深入探讨如何找到一个序列中长度最长的递增子序列。 ...

    最长递增子序列LCS的实现C源码

    最长递增子序列(Longest Increasing Subsequence, LCS)是计算机科学中一种经典的动态规划问题,常见于算法和数据结构的学习。在这个问题中,我们给定一个无序整数序列,目标是找到序列中的一个子序列,使得这个子...

    LIS最长单调递增子序列

    在LIS问题中,我们可以定义一个dp数组,其中dp[i]表示以序列中的第i个元素结尾的最长递增子序列的长度。通过遍历整个序列,我们可以更新dp数组,从而得到最终的LIS长度。 以下是解决LIS问题的基本步骤: 1. 初始化...

    求取最长递增子序列(MFC编程)

    最长递增子序列(Longest Increasing Subsequence, LIS)是计算机科学中一个经典的算法问题,主要涉及到了排序、数组处理和优化策略等概念。在这个场景中,我们将关注使用贪心算法和动态规划来解决这个问题,并结合...

    排序最长递增子序列红黑树

    标题中的“排序最长递增子序列红黑树”是指在数据结构和算法领域中的两个重要概念:排序和最长递增子序列(Longest Increasing Subsequence, LIS),以及它们与红黑树(Red-Black Tree)的关联。在这个场景中,我们...

    最长递增子序列C程序

    最长递增子序列(Longest Increasing Subsequence, LIS)问题是一个经典的计算机科学问题,它在动态规划、算法设计和序列分析等领域都有广泛的应用。在这个C程序中,我们将深入探讨如何利用C语言来解决这个问题。 ...

    LIS 最长递增子序列 Java的简单实现

    最长递增子序列(Longest Increasing Subsequence, LIS)是计算机科学中的一种经典问题,它在数组或序列中寻找一个尽可能长的递增子序列。这个问题具有多种应用,如在股票交易策略、优化调度和生物信息学等领域都...

    算法实验(整数划分、各类排序、最长递增子序列、幻方矩阵)

    本实验涵盖了几个重要的算法概念,包括整数划分、排序算法、最长递增子序列以及幻方矩阵。下面将逐一详细介绍这些知识点。 1. 整数划分: 整数划分是一个数学问题,它涉及将一个正整数n划分为若干个正整数的和,...

    js代码-求最长递增子序列

    在JavaScript编程中,"求最长递增子序列"(Longest Increasing Subsequence,LIS)是一个经典的动态规划问题。该问题旨在找到一个数组中的最长子序列,使得子序列中的元素顺序是递增的,但子序列不必是连续的。这个...

    最长递增子序列的另外一种C语言实现代码

    最长递增子序列(Longest Increasing Subsequence, LIS)是计算机科学中的一种经典算法问题,主要出现在算法设计与分析的课程中。这个问题的目标是从给定的一组整数中找到一个尽可能长的严格递增的子序列。在本例中...

    最长递增子序列(LIS)问题是一个经典的动态规划问题 给定一个数组,我们要找到其中最长的严格递增子序列的长度

    最长递增子序列(LIS)问题是一个经典的动态规划问题。给定一个数组,我们要找到其中最长的严格递增子序列的长度。子序列可以通过删除(或不删除)数组中的一些元素而不改变其余元素的顺序来派生。

    算法题:最长递增子序列(Longest Increasing Subsequence, LIS).pdf

    ### 最长递增子序列(Longest Increasing Subsequence, LIS) #### 题目描述 本题要求在给定的一个无序整数数组 `nums` 中寻找最长递增子序列的长度。递增子序列指的是数组中的一个序列,其中每个元素都严格大于前...

Global site tag (gtag.js) - Google Analytics