最长递减子序列
2012-08-12 19:30 coodoing 阅读(2755) 评论(0) 编辑 收藏 举报问题描述
求一个数组的最长递减子序列比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}。
问题分析
本问题类似编程之美中的求数组中最长递增子序列问题。可以利用动态规划方法解决。
假设在目标数组array[]的前i个元素中,最长递减子序列的长度为LDS[i]。那么
LDS[i+1] = max{1,LDS[k]+1},其中array[i+1]<array[k],for any k<=i。
即如果array[i+1]<array[k],那么第i+1个元素可以添加到LDS[k]长的子序列后构成一个更长的递减子序列。与此同时,
array[i+1]可以由自身构造成一个长度为1的子序列。
所以代码清单为:
for (int i = 0; i < len; i++) { LDS[i] = 1; for (int k = 0; k < i; k++) { // LDS[i+1]=max{1,LDS[k]+1}, array[i+1]<array[k],for any k<=i; if (array[i] < array[k] && LDS[k] + 1 > LDS[i]) { LDS[i] = LDS[k] + 1; } } }
在获取到LDS数组后,遍历数组,获取构成最长递减子序列的元素。
print(int[] array, int[] lds, int max, int end) { if (max == 0) return; int i = end; while (lds[i] != max) i--; print(array, lds, max - 1, i - 1); System.out.print(array[i] + ""); }
实现代码
1: public class LDSProblem {
2: public static void maxSubstrDecrease(int[] array) {
3: // 数组array中的前i个元素中,最长递减子序列的长度是LDS[i]
4: int len = array.length;
5: int[] LDS = new int[len];
6: int max = 0;
7: for (int i = 0; i < len; i++) {
8: LDS[i] = 1;
9: for (int k = 0; k < i; k++) {
10: // LDS[i+1]=max{1,LDS[k]+1}, array[i+1]<array[k],for any k<=i;
11: if (array[i] < array[k] && LDS[k] + 1 > LDS[i]) {
12: LDS[i] = LDS[k] + 1;
13: }
14: }
15: }
16: max = maxsub(LDS);
17: System.out.println("最长递减子序列的长度为:" + max);
18: System.out.println("LDS数组为:");
19: print(LDS);
20: System.out.print("最长递减子序列为:\n");
21: print(array, LDS, max, len - 1);
22: }
23:
24: // max:最长子序列长度
25: // end:最长递减子序列中的最后一个元素
26: // lds:数组array中的前i个元素中,最长递减子序列的长度数组
27: private static void print(int[] array, int[] lds, int max, int end) {
28: if (max == 0)
29: return;
30: int i = end;
31: while (lds[i] != max)
32: i--;
33: print(array, lds, max - 1, i - 1);
34: System.out.print(array[i] + " ");
35: }
36:
37: private static void print(int[] array) {
38: for (int i = 0; i < array.length; i++) {
39: System.out.print(array[i] + " ");
40: }
41: System.out.println();
42: }
43:
44: public static int maxsub(int[] LDS) {
45: int m = 0;
46: for (int i = 0; i < LDS.length; i++) {
47: if (LDS[i] > m)
48: m = LDS[i];
49: }
50: return m;
51: }
52:
53: public static void main(String[] args) {
54: int[] array = new int[] { 9, 4, 3, 2, 5, 4, 3, 2 };
55: /* System.out.println("数组为:");
56: print(array);*/
57: maxSubstrDecrease(array);
58: }
59: }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现