前言动态规划:与分治法相似,即通过组合子问题来求解原问题,不同的是分治法是将问题划分为互不相交的子问题,递归求解子问题,再将他们组合起来求出原问题的解。

动态规划则应用于子问题重叠的情况,通常用来求解最优化问题。这类问题可以有很多可行解,每个解都有一个值,我们希望寻找最优值的解。

通常有4个步骤来设计动态规划算法:

1.刻画一个最优解的结构特征。

2.递归地定义最优解的值。

3.计算最优解的值,通过采用自底向上的方法。

4.利用计算出的信息构造一个最优解。

【问题1】最长递增子序列问题

【问题描述】设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<ak1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm。求最大的m值。

采用一个数组temp[]保存 以当前元素结尾的最长递增子序列长度,最后求出全局最优解

更新最长递增子序列的条件:a[i]>a[j]  (i>j) 且前一个递增序列长度大于等于当前递增序列长度

[html]  view plain copy
  1. //动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。
  2. //最长递增子序列O(N^2)
  3. public void longestIncreasingSubsequence2(int[] a){
  4. int[] temp=new int[a.length];
  5. temp[0]=1;
  6. int max=0;
  7. for(int i=1;i<a.length;i++){
  8. temp[i]=1;
  9. for(int j=0;j<i;j++){
  10. if(a[i]>a[j]&&temp[i]<=temp[j]){//找出最大的temp[j](前一个最长递增子序列长度)temp[i]<=temp[j]
  11. temp[i]=temp[j]+1;//更新最长递增子序列长度
  12. }
  13. }
  14. max=Math.max(temp[i], max);
  15. }
  16. System.out.println(max);
  17. }

【改进】考虑到在计算每个temp[i]时都要找到最大的,由于数组无序,所以每次都需要顺序查找。可以让数组有序那么就可以使用二分查找,从而算法复杂度就可以降到O(NlogN)。可以采用一个数组存储最大递增子序列的最末元素:即: B[ temp[j] ] = aj。

在数组B中用二分查找法找到满足j<i且B[f(j)]=aj<ai的最大的j,并将B[f[j]+1]置为ai。

[html]  view plain copy
  1. //O(NlogN)解法
  2. public void longestIncreasingSubsequence(int[] a){
  3. /*
  4. * 在计算每一个f(i)时,都要找出最大的f(j)(j<i)来,由于f(j)没有顺序,只能顺序查找满足aj<ai最大的f(j),
  5. * 如果能将让f(j)有序,就可以使用二分查找,这样算法的时间复杂度就可能降到O(nlogn)。
  6. * 于是想到用一个
  7. * 数组B来存储“子序列的”最大递增子序列的最末元素,
  8. * 即有B[f(j)] = aj
  9. *  在计算f(i)时,在数组B中用二分查找法找到满足j<i且B[f(j)]=aj<ai的最大的j,并将B[f[j]+1]置为ai。
  10. */
  11. int[] temp=new int[a.length+1];
  12. temp[0]=-100;
  13. temp[1]=a[0];
  14. int Len=1;
  15. int p,r,m;//p,r,m分别为二分查找的上界,下界和中点;
  16. for(int i = 1;i<a.length;i++)
  17. {
  18. p=0;r=Len;
  19. while(p<=r)//二分查找最末元素小于ai+1的长度最大的最大递增子序列;
  20. {
  21. m = (p+r)/2;
  22. if(temp[m]<a[i]) p = m+1;
  23. else r = m-1;
  24. }
  25. temp[p] = a[i];//将长度为p的最大递增子序列的当前最末元素置为ai+1;
  26. if(p>Len) Len++;//更新当前最大递增子序列长度;
  27. }
  28. System.out.println(Len);
  29. }

【TreeSet解法】treeSet底层是使用红黑树实现,因此可以按照值的升序进行排序。

[html]  view plain copy
  1. set.ceiling(i)返回set集合中比i大的最小元素。
[html]  view plain copy
  1. public int lengthOfLIS2 (int[] nums) {
  2. /*
  3. * TreeSet是一个有序集合,TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列,
  4. * 意味着TreeSet中的元素要实现Comparable接口。或者有一个自定义的比较器。
  5. * 我们可以在构造TreeSet对象时,传递实现Comparator接口的比较器对象。
  6. */
  7. TreeSet<Integer> set = new TreeSet<>();
  8. for(int i : nums) {
  9. //Returns the least element in this set greater than or equal to the given element,
  10. //or null if there is no such element.
  11. Integer ceil = set.ceiling(i);
  12. if(null != ceil) {
  13. set.remove(ceil);
  14. }
  15. set.add(i);
  16. }
  17. return set.size();
  18. }

【问题2】最长不重复子串问题
【问题描述】Given a string, find the length of the longest substring without repeating characters.

搜索过程如下:记录上一次最长子串起始位置last,然后进行下一次搜索。比较得到最长不重复子串

[html]  view plain copy
  1. public int lengthOfLongestSubstring(String s) {
  2. if(s.length()==0||s.length()==1)
  3. return s.length();
  4. char[] sArr=s.toCharArray();
  5. int last=0;
  6. int result=-1;
  7. int[] dp=new int[sArr.length];
  8. dp[0]=1;
  9. for(int i=1;i<sArr.length;i++){
  10. for(int j=i-1;j>=last;j--){
  11. if(sArr[i]==sArr[j]){
  12. last=j+1;//更新上一次最长子串起始位置
  13. dp[i]=i-j;//最长不重复子串
  14. break;
  15. }else if(j==last){
  16. dp[i]=dp[i-1]+1;//都不重复则更新最长不重复子串
  17. }
  18. }
  19. result=Math.max(dp[i], result);
  20. }
  21. return result;

【问题3】两个序列的最长公共子序列

既然是经典的题目肯定是有优化空间的,并且解题方式是有固定流程的,这里我们采用的是矩阵实现,也就是二维数组,用来LCS的长度。

第一步:先计算最长公共子序列的长度。

第二步:根据长度,然后通过回溯求出最长公共子序列。

现有两个序列X={x1,x2,x3,...xi},Y={y1,y2,y3,....,yi},

设一个C[i,j]: 保存Xi与Yj的LCS的长度。

递推方程为:
        

[html]  view plain copy
  1. //最长公共子序列
  2. public int LCS(int[] a,int[] b){
  3. int[][] temp=new int[a.length+1][b.length+1];
  4. int result=0;int dp=0;
  5. for(int i=1;i<=a.length;i++)
  6. temp[i][0]=0;
  7. for(int j=0;j<=b.length;j++)
  8. temp[0][j]=0;
  9. for(int k=1;k<=a.length;k++){
  10. for(int l=1;l<=b.length;l++){
  11. if(a[k-1]==a[l-1])
  12. temp[k][l]=temp[k-1][l-1]+1;
  13. else if(temp[k][l-1]<=temp[k-1][l])
  14. temp[k][l]=temp[k][l-1];
  15. else
  16. temp[k][l]=temp[k-1][l];
  17. result=Math.max(temp[k][l], result);
  18. }
  19. }
  20. return result;
  21. }

动态规划的一个重要性质特点就是解决“子问题重叠”的场景,可以有效的避免重复计算,根据上面的公式其实可以发现C[i,j]一直保存着当前(Xi,Yi)的最大子序列长度。

动态规划之最长递增子序列 最长不重复子串 最长公共子序列相关推荐

  1. 最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和...

    最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和 文章作者:Yx.Ac   文章来源:勇幸|Thinking (http://www.ahathi ...

  2. java 最长不重复子串,最长无重复字符子串

    正文在下面,先打个广告: 问题描述: 输入:abdca 返回:abdc 方法一:使用双指针(滑动窗口)来实现.该方法需要配合map保存已经出现过的字符. public static int maxLe ...

  3. leetcode1143. 最长公共子序列(动态规划)

    给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度. 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删 ...

  4. LeetCode 1143. 最长公共子序列(动态规划)

    1. 题目 给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度. 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符 ...

  5. C语言(CED)最长公共子序列----动态规划第一题

    一.动态规划算法与分治法的异同 相同点: A.二者均是将待求解的问题分成若干子问题来求解. B.二者在编写代码的时候,都要用到递归. 不同点: A.分治法求解的问题,在将问题分成若干子问题之后,其子问 ...

  6. 【51NOD】1006 最长公共子序列Lcs(动态规划)

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最 ...

  7. 最长公共子序列问题 (LCS)

    最长公共子序列问题 : 1>给两个子序列A和B,求长度最大的公共子序列.例如1,5,2,6,8,7和2,3,5,6,9,8,4的最长公共子序列为5,6,8(另一个解是2,6,8). 2>我 ...

  8. 矩阵中的最长递增路径

    矩阵中的最长递增路径 文章目录 矩阵中的最长递增路径 一.问题描述 **方法一:朴素的深度优先搜索 [超时]** **方法二:记忆化深度优先搜索 [通过]** **方法三:动态规划** **方法四:广 ...

  9. 数据结构与算法专题——第三题 最长公共子序列

    一:作用 最长公共子序列的问题常用于解决字符串的相似度,是一个非常实用的算法,作为码农,此算法是我们的必备基本功. 二:概念 举个例子,cnblogs这个字符串中子序列有多少个呢?很显然有27个,比如 ...

最新文章

  1. 同类分析比较工具 google trend
  2. MySql里的My是指谁?
  3. 【渝粤题库】陕西师范大学210015幼儿园社会教育作业(高起专)
  4. 视频(avi)转换为图片(Python代码实现)
  5. 什么是三层架构?它的优点是什么?_三层实木和多层实木地板各有什么优劣点
  6. 【BZOJ4660】Crazy Rabbit 结论+DP
  7. 集腋成裘-13-git使用-02进阶篇
  8. Java SE书籍推荐
  9. GitHub 项目精选(2022.5.18更新)
  10. 转:施炜:铁军组织是怎样炼成的?高能组织=人×管理体系×数字标准
  11. java技术cad转图片,怎么把原有的cad文件转换成图片格式?快速把cad转jpg的技巧...
  12. Kryo官方文档-中文翻译
  13. 福建福州软考考点安排在哪?
  14. 文本单词统计(C语言)
  15. ubuntu配置静态ip的方法
  16. awk命令在ps -ef中的应用
  17. 干掉AlibabaProtect【windows10】
  18. x264 自适应量化模式 (AQ Adaptive Quantization) 初探
  19. Android 游戏破解
  20. Android之 颜色选择器

热门文章

  1. 选择器的分类及其优先级
  2. C#支持正负数的数字正则验证表达式
  3. UTF-8转为ASCII(转)
  4. spark sql 之 collect_set collect_list 后WrappedArray 取值
  5. Ubuntu 20.04 开启麦克风降噪功能
  6. 使用Chinese-Word-Vectors作为pytorch中的预训练向量
  7. 图像算法工程师岗位的主要职责(合集)
  8. 51CTO专访人人网黄晶:WEB开发需要随需应变(2)
  9. OCP-V13-700
  10. 【Latex 表格】换行+行高