`
hengjie10
  • 浏览: 24163 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

最长单调递增子序列

 
阅读更多

问题描述:
找出由n个数组成的序列的最长单调递增子序列

解法一:

原序列记为X,对n个数递增排序,构造一个新序列Y, 对X,Y求其最长公共子序列即可.

/*
 * 最长单调递增子序列
 * 问题描述:
 * 找出由n个数组成的序列的最长单调递增子序列
 * 算法设计:
 * 解法一:
 * 原序列记为X,对n个数递增排序,构造一个新序列Y, 对X,Y求其最长公共子序列即可.
 * 
 * auther:thj
 * date:2010/11/17
 */
import java.util.LinkedList;
import java.util.List;
public class LISLength 
{
	private int[] arrX;
	private int[] arrY;
	private int[][] c;

	public LISLength(int[] arr)
	{
		arrX = new int[arr.length + 1];
		arrY = new int[arr.length + 1];
		System.arraycopy(arr,0,arrX,1,arr.length);
		System.arraycopy(arr,0,arrY,1,arr.length);
		selectSort(arrY, arrY.length - 1);
		lisLength();
	}

	//计算最长公共子序列
	public void lisLength()
	{
		c = new int[arrX.length][arrY.length];

		for (int i = 1; i < arrX.length; i++)
		{
			for (int j = 1; j < arrY.length; j++)
			{
				if (arrX[i] == arrY[j])
				{
					c[i][j] = c[i-1][j-1] + 1;
				}
				else
				{
					c[i][j] = max(c[i-1][j], c[i][j-1]);
				}
			}
		}
	}

	//返回最长单调递增子序列
	public List<Integer> getLIS()
	{
		LinkedList<Integer> list = new LinkedList<Integer>();
		int i = arrX.length - 1;
		int j = arrY.length - 1;
		while (i >= 1 && j >= 1)
		{
			if (arrX[i] == arrY[j])
			{
				list.addFirst(Integer.valueOf(arrX[i]));
				i--;
				j--;
			}
			else
			{
				if (c[i-1][j] > c[i][j-1])
				{
					i--;
				}
				else
				{
					j--;
				}
			}
		}
		return list;
	}

	private int max(int m, int n)
	{
		return m > n ? m : n;
	}

	//选择排序,0号空间不用
	private void selectSort(int[] a, int n)
	{
		for (int i = 1; i < n; i++)
		{
			int k = i;
			for (int j = i + 1; j <= n; j++)
			{
				if (a[k] > a[j])
				{
					k = j;
				}
			}
			if (k != i)
			{
				int temp = a[k];
				a[k] = a[i];
				a[i] = temp;
			}
		}
	}

	public static void main(String[] args) 
	{
		int[] arr = {5,2,4,6,5,1,8};
		
		LISLength lis = new LISLength(arr);
		List<Integer> a = lis.getLIS();
		for (Integer item: a)
		{
			System.out.print(item + " ");
		}
	}
}

序列X={5, 2, 4, 6,5,1, 8}

执行结果:

2 4 5 8

解法二:
1)用一个数组b[n]记录以a[i]结尾的最长单调递增子序列的长度;
2)序列的a的最长单调子序列的长度为max{b[i],0=<i<n};
3)b[i] = max{b[k],a[k]<=a[i]&&0=<k<i} + 1 ,b[0] = 1;

/*
 * 最长单调递增子序列
 * 问题描述:
 * 找出由n个数组成的序列的最长单调递增子序列
 * 算法设计:
 * 解法二:
 * 1)用一个数组b[n]记录以a[i]结尾的最长单调递增子序列的长度;
 * 2)序列的a的最长单调子序列的长度为max{b[i],0=<i<n};
 * 3)b[i] = max{b[k],a[k]<=a[i]&&0=<k<i} + 1 ,b[0] = 1;
 * 
 * auther:thj
 * date:2010/11/17
 */
public class LIS
{
	private int[] a;
	private int[] b;

	public LIS(int[] a)
	{
		this.a = a;
		b = new int[a.length];
	}

	public void lis()
	{
		b[0] = 1;

		for (int i = 0; i < a.length; i++)
		{
			int k = 0;
			for (int j = 0; j < i; j++)
			{
				if (a[j] <= a[i] && k < b[j])
				{
					k = b[j];
				}
			}
			b[i] = k + 1;
		}
		int k = max(b);
                //输出结果
		print(k);
	}

	//求数组中最大值下标
	private int max(int[] b)
	{
		int max = b[0];
		int k = 0;
		for (int i = 0; i < b.length; i++)
		{
			if (max < b[i])
			{
				max = b[i];
				k = i;
			}
		}
		return k;
	}

	//输出
	public void print(int k)
	{
		for (int i = k - 1; i >= 0; i--)
		{
			if (b[k] == b[i] + 1 && a[i] <= a[k])
			{
				print(i);
				break;
			}
		}
		System.out.print(a[k] + " ");
	}

	public static void main(String[] args) 
	{
		int[] a = {5, 2, 4, 6, 5, 1, 8};
		LIS lis = new LIS(a);
		lis.lis();
	}
}

序列X={5, 2, 4, 6,5,1, 8}

执行结果:

2 4 5 8




分享到:
评论
1 楼 yscyfy 2013-05-15  
第一中算法没考虑 重复元素吧

相关推荐

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

    ### 动态规划:最长单调递增子序列 在计算机科学和算法设计中,动态规划是一种重要的技术,用于解决优化问题。本篇文章将详细介绍如何利用动态规划求解一个经典问题——寻找给定序列中的最长单调递增子序列...

    最长单调递增子序列(O(n2)).rar_company7ne_最长单调递增子序列(动态规划法)

    最长单调递增子序列(LIS,Longest Increasing Subsequence)是计算机科学中一个经典的问题,主要涉及到序列处理和算法设计。在这个问题中,我们给定一个整数序列,目标是找到序列中的一个子序列,使得这个子序列是...

    动态规划问题-最长单调递增子序列问题

    L={a1,a2,a3,…,an},是由n个不同的实数组成的序列,求L的最长单调递增子序列的长度(下标可不连续)

    LIS最长单调递增子序列

    最长单调递增子序列(Longest Increasing Subsequence, LIS)是计算机科学中一种经典的问题,主要涉及算法设计和分析,特别是在动态规划领域的应用。在这个问题中,我们需要在给定的一个整数序列中找出一个尽可能长...

    单调递增序列

    设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

    最长的单调递增子序列

    例如,序列{1, 7, 4, 9, 2, 8}的一个最长单调递增子序列是{1, 4, 7, 9}。 在提供的代码中,我们看到使用了C++语言来实现求解最长单调递增子序列的方法。核心函数`result_assend`接收三个参数:一个整数数组`a`,...

    最长递增子序列的求法

    最长递增子序列问题是一个很基本、较常见的小问题,但这个问题的求解方法却并不那么显而易见,需要较深入的思考和较好的算法素养才能得出良好的算法。由于这个问题能运用学过的基本的算法分析和设计的方法与思想,...

    算法之动态规划---单调递增子序列

    根据给定的文件信息,我们将深入探讨两个关键的IT领域知识点:动态规划在寻找最长单调递增子序列中的应用以及动态规划在图像压缩算法中的作用。 ### 一、动态规划与最长单调递增子序列 #### 知识点概述: **最长...

    单调递增子序列

    最长单调递增子序列,运行时间为O(nlgn),为算法导论上的算法

    最长单调递增子序列LIS

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

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

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

    最长递增子序列

    算法导论,请给出一个O(n^2)时间的算法,使之能找出n个数的序列中最长的单调递增子序列

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

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

    单调递增子序列 最大连续子段和

    单调递增子序列(Longest Increasing Subsequence, LIS) **定义**:在数组或序列中找到最长的子序列,使得该子序列中的元素按顺序严格递增。 **应用场景**: - 在算法竞赛中,LIS 是一个非常常见的问题。 - 在...

    算法与设计2

    - **路径**:一系列顶点和边的序列,表示从一个顶点到另一个顶点的可能行走路线。 - **迹**:路径的一种,其中所有的边都不重复。 - **路**:迹的一种,其中所有的顶点都不重复。 - **闭路径**:起点和终点相同的...

    最长递增子序列1

    最长递增子序列(LIS)是数组或序列中一个重要的概念,它的目标是找到一个序列的最长子序列,使得这个子序列中的元素是严格递增的。在给定的描述中,我们看到了三种不同的方法来求解LIS问题。 **方法一:动态规划...

    实验二--动态规划.docx

    实验中,学生将设计一个时间的算法,找出由 n 个数组成的序列的最长单调递增子序列,并解决二维 0-1 背包问题。 二、实验工具 本实验所需的工具是 JDK 1.8 和 Eclipse IDE for Java EE Developers。 三、实验题 ...

    动态规划解决算法0~1背包问题实验报告(含源代码).doc

    最长单调递增子序列问题是指,给定一个序列,找出该序列的最长单调递增子序列。该问题可以使用动态规划法和排序算法解决。 本实验报告展示了动态规划法解决0/1背包问题的实验结果,并讨论了其他几种算法在解决该...

    计算机算法设计与分析总课件.ppt

    本课件主要涵盖了三个经典的算法问题:寻找数组中的最大值和次大值、计算数列的最大子段和以及找出序列中最长单调递增子序列。 1. **寻找数组中的最大值和次大值** - **算法思路**:这个算法采用递归策略。当数组...

Global site tag (gtag.js) - Google Analytics