给定一个无序的整数数组,找到其中最长上升子序列的长度。
输入: [10,9,2,5,3,7,101,18]
输出: 4

纯DP

解体思路:利用动态规划的方法,从一个方向遍历数组,每次获取以该位置为子序列结尾的长度。状态表示,利用数组f分别表示以该位结尾的最长上升子序列;状态转移,像前遍历,如果前者比后者小,则取二者最大长度,最后在加一,表示加上当前位。

PS:现在做dp的题自然而然能够想到闫氏DP分析法,首先想到如何用数组表示每个状态,再去思考怎么递推状态。

class Solution {
public int lengthOfLIS(int[] nums) {
int n = nums.length;
// 状态表示
int[] f = new int[n];
int res = 0; for(int i = 0; i < n; i++) {
int cur = 0;
for(int j = i - 1; j >= 0; j--) {
if(nums[i] > nums[j]) {
// 获取前面最长子序列
cur = Math.max(f[j], cur);
}
}
// 状态转移
f[i] = cur + 1;
res = Math.max(f[i], res);
} return res;
}
}

DP + 二分

解题思路:遍历数组,利用一个队列,保存遍历时当前的最长子序列。然后通过二分的方法,查找当前元素在队列中的位置,如果当前元素在队列元素的范围之内,则替换第一个大于等于它的元素,如果当前元素大于队列的最大元素,则直接将当前元素放在最后,同时最长子序列的值增加1。

  • 为什么可以替换中间的值?
    因为替换的是第一个大于等于它的值,这样既可以保持队列递增,还可以降低队列元素的值。
class Solution {
public int lengthOfLIS(int[] nums) {
int[] f = new int[nums.length];
int res = 0;
for(int num : nums) {
int l = 0, r = res;
while(l < r) {
int mid = l + r >> 1;
if(f[mid] >= num) {
r = mid;
} else {
l = mid + 1;
}
} f[r] = num;
if(res == r) res ++;
} return res;
}
}

算法——最长上升子序列(DP和二分)的更多相关文章

  1. POJ-2533最长上升子序列(DP+二分)(优化版)

    Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 41944   Acc ...

  2. Bzoj 3173: [Tjoi2013]最长上升子序列 平衡树,Treap,二分,树的序遍历

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1183  Solved: 610[Submit][St ...

  3. 编程算法 - 最长上升子序列问题 代码(C)

    最长上升子序列问题 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有一个长为n的数列a. 请求出这个序列中最长上升子序列的长度. 最长上升子序 ...

  4. 编程算法 - 最长公共子序列(LCS) 代码(C)

    最长公共子序列(LCS) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定两个字符串s,t, 求出这两个字符串最长的公共子序列的长度. 字符 ...

  5. LCS最长公共子序列~dp学习~4

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 Palindrome Time Limit: 4000/2000 MS (Java/Others ...

  6. Longest Ordered Subsequence POJ - 2533 最长上升子序列dp

    题意:最长上升子序列nlogn写法 #include<iostream> #include<cstdio> #include<cstring> #include&l ...

  7. POJ 1458 最长公共子序列(dp)

    POJ 1458 最长公共子序列 题目大意:给出两个字符串,求出这样的一 个最长的公共子序列的长度:子序列 中的每个字符都能在两个原串中找到, 而且每个字符的先后顺序和原串中的 先后顺序一致. Sam ...

  8. 动态规划算法——最长公共子序列问题(java实现)

    已知序列X=(A,B,C,A,B,D,A)和序列Y=(B,A,D,B,A),求它们的最长公共子序列S. /* * LCSLength.java * Version 1.0.0 * Created on ...

  9. 【BZOJ2423】[HAOI2010]最长公共子序列 DP

    [BZOJ2423][HAOI2010]最长公共子序列 Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...

随机推荐

  1. 年轻人不讲武德来白piao我这个老同志

    朋友们好啊,我是码农小胖哥. 今天有个同学问我在吗,我说什么事? 给我发个截图,我一看!噢,原来是帮忙搞个定时任务,还是动态的. 他说了两种选择,一种是用DelayQueue,一种是用消息队列. 他说 ...

  2. ceph osd tree的可视化

    前言 很久没有处理很大的集群,在接触一个新集群的时候,如果集群足够大,需要比较长的时间才能去理解这个集群的结构,而直接去看ceph osd tree的结果,当然是可以的,这里是把osd tree的结构 ...

  3. FreeMark导出word文件

    1.编辑好word 2.将word模板另存为xml格式, 把需要动态生成的文字用${xxx}代替 eg: 张强 替换为:${name} 注意:图片是很长的一个base64的字符,同样替换就好 比如替换 ...

  4. 用十一张图讲清楚,当你CRUD时BufferPool中发生了什么!以及BufferPool的优化!

    一.收到了大佬们的建议 1.篇幅偏短,建议稍微加长一点. 这点说的确实挺对,有的篇幅确实比较短,针对这个提议我会考虑将相似的话题放在一篇文章中.但是这可能会导致我中断每天更新的步调,换成隔几天发一篇的 ...

  5. Java的比较器Comparable与Comparator

    在Java中有两个比较器:Comparable.Comparator 对于Integer.Double等等类型,可以直接对他们进行比较,因为已经实现了比较的方式,然而在平时常常会面临需要对集合进行排序 ...

  6. Jmeter监控插件

    Jmeter-Plugins支持CPU.Memory.Swap.Disk和Network的监控,在测试过程中更加方便进行结果收集和统计分析. 一.准备工作: 1.下载Jmeter-Plugins插件, ...

  7. IDM下载器的自定义设置

    IDM(Internet Download Manager)下载器主窗口的左侧是下载类别的分类,提供了分类功能来组织和管理文件.如果不需要它,可以删除"分类"窗口,并且在下载文件时 ...

  8. 人人都能学会系列之ThreadLocal

    1.概览 本文我们来看下java.lang包中的ThreadLocal,它赋予我们给每个线程存储自己数据的能力. 2.ThreadLocal API ThreadLocal允许我们存储的数据只能被特定 ...

  9. appium元素定位总结

    appium元素定位方法总结 使用uiautomator定位 driver.find_element_by_android_uiautomator(uia_string) 根据resourceId属性 ...

  10. So Easy! HDU - 4565

    易知,有\(S_n = \lceil{a + \sqrt{b}}\rceil ^ n\) \(\because a ^ 2 - 1 < b < a ^ 2\) \(\therefore a ...