`
shuofenglxy
  • 浏览: 189559 次
  • 性别: 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
分享到:
评论

相关推荐

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

    中科大软件学院 算法导论课程实验 正式题目二 最长递增子序列 Visual Studio 2012 项目包 使用4种不同的方法实现最长递增子序列

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

    中科大软件学院 算法导论课程实验 正式题目二 最长递增子序列 实验报告 使用4种不同的方式实现最长递增子序列

    LIS最长单调递增子序列

    使用动态规划思想求出最长单调递增子序列(LIS),时间复杂度为O(n log k)

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

    还提供了一个用于区分列表的功能,该功能利用了 LIS 算法。

    最长单调递增子序列LIS

    我写的LIS算法,有两种思路,程序全在这个cpp文件中,可以运行

    LIS:最长递增子序列作业,图形界面

    ##算法最长递增子序列时间复杂度O(nlogn)##接口JAVA swing ##功能更改输入字符串的长度随机生成输入字符串标记输入字符串中最长的递增子序列

    dowalle#algo#300-[LIS]-最长递增子序列1

    1. 定义状态: 2. 状态转移方程: 3. 初始化: 4. 输出: 5. 空间优化: 1 .定义新状态: 2. 状态转移方程: 3. 初始化: 4. 输出:

    论文研究-生物信息挖掘中LIS算法研究.pdf

    探讨了生物信息挖掘中ó模式子序列问题的一个特例,即最长递增子序列(LIS)问题。对于LIS问题,分别用LCS算法、动态规划、动态规划结合二分法进行求解,并分析了这三种算法的时间和空间复杂度,对其中两种算法进行了...

    算法设计与分析实验报告

    校门外的树、字符串子序列、6种排序算法分析、最长递增子序列,算法分析

    c语言最长上升子集.rar

    最长上升子序列问题可以这样定义:给定一个无序的整数数组,任务是找到该数组中一个最长的子序列,使得这个子序列中的元素从左到右是严格递增的。这里的“子序列”是指从原数组中挑选出的一些元素,它们保持原序列中...

    javalruleetcode-magician:java学习

    最长递增子序列 MaxLength: 无环有向图最长加权路径 LPS: 最长回文子序列 Knapspack: 01背包问题 ####贪心算法 ActiveSelect: 活动选择问题 IGCP: 区间染色问题 ####图算法 ListGraph: 邻接链表表示法 Transpose: ...

    leetcode表现最好的时间段-DP-Interviews:DP-面试

    最长递增子序列 使序列排序的最小删除次数 经典的 LIS 问题。 找到序列的 LIS 和deletions = arr.length - LIS.length (非常类似于双调序列) 选择最后一个操作的所有可能间隔中的所有可能削减 在这里解释—— ...

    algorithoms:进阶算法

    数组中最长的递增子序列在最长增加子序列(LIS)问题中,找到给定序列的最长子序列的长度,以使该子序列的所有元素都按升序排序 Ex: Input : arr[] = {3, 10, 2, 1, 20,4,56,78,90} Output : Length of LIS = 6 ...

    leetcode刷题app-blog:问题博客

    leetcode刷题app 面试 Google 招聘的网上算法试场,一般一场打进前40可能会收到Google的面试邀约 ...最长递增子序列 - LIS(Longest Increasing Subsequence) 2.3 01背包 - 01 Knapsack 3. 数据结构 3.1 二叉搜索树

Global site tag (gtag.js) - Google Analytics