01 前言

1.1 说明

关于动态规划的见解:动规和递归有很多相似的地方,最显著的特征可以说是阶段性,二者都有很明显的阶段划分,所以,声明好每一个阶段所需要做的事情以及阶段与阶段之间的转移可以说是重中之重了,这就涉及几个问题:

  • 第一,需要声明好方法(递归)或者数组(动规)具体的意义,所代表的作用;
  • 第二,需要说明好递归处理数据的方式(递归)或者是阶段转移方程(动规);
  • 第三,跳出方法的条件(递归)或者是数组边界条件(动规)。

处理好这三个方面,基本上就没有问题,剩下的就是一些边边角角的问题。

1.2 提炼

  • 声明数组代表的含义
  • 状态转移方程
  • 边界条件

除了动态规划的4个题型的分析,小编最近还整理了66个Java面试的知识点哦(提示:文末有福利)

02 4个经典题型

2.1 数字金字塔

(1)问题描述

观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以从当前点走到左下方的点也可以到达右下方的点。

在上面的样例中,从13到8到26到15到24的路径产生了最大的和86。

(2)输入

第一个行包含R(1<= R<=1000),表示行的数目。

后面每行为这个数字金字塔特定行包含的整数。

所有的被供应的整数是非负的且不大于100。

(3)输出

单独的一行,包含那个可能得到的最大的和。

(4)样例输入

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">5 //数塔层数
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
</pre>

(5)样例输出

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">86
</pre>

(6)代码1

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">    /*** 顺推 dp* 含义:f[x][y] 从0,0到x,y最大值* 方程:f[x][y] = max{f[x-1][y],f[x-1][y-1]} + a[x][y]* 边界:f[0][0] = a[0][0]* */public int positive(int[][] a) {int[][] f = new int[a.length][a.length];// 边界f[0][0] = a[0][0];// 状态转移方程int i,j;for (i=1; i<a.length; i++) {for (j=0; j<=i; j++) {/*判断是否数组越界,左右两边需单独处理*/if (j == 0) {f[i][j] = f[i-1][j] + a[i][j];} else if (j == i) {f[i][j] = f[i-1][j-1] + a[i][j];} else {int max = f[i-1][j] > f[i-1][j-1] ? f[i-1][j] : f[i-1][j-1];f[i][j] = max + a[i][j];}}}// 获取最大值int temp = 0;for (i=0; i<a.length; i++) {if (f[a.length-1][i] > temp) {temp = f[a.length-1][i];}}return temp;}
</pre>

(7)代码2

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">    /*** 逆推* 含义:f[x][y]表示从x,y到终点的最大值,所以f[0][0]即为所求* 公式:f[x][y] = max{f[x+1][y+1],f[x+1][y]} + a[x][y]* 边界:f[length-1][0...length-1] = a[length-1][0...length-1]* */public int negative(int[][] a) {int[][] f = new int[a.length][a.length];// 边界int i,j;for (i=0; i<a.length; i++) {f[a.length-1][i] = a[a.length-1][i];}// 状态转移for (i=a.length-2; i>=0; i--) {for (j=0; j<=i; j++) {int max = f[i+1][j+1] > f[i+1][j] ? f[i+1][j+1] : f[i+1][j];f[i][j] = max + a[i][j];}}return f[0][0];}
</pre>

2.2 最长不下降子序列

(1)问题描述

设有由n个不相同的整数组成的数列,记为:b(1)、b(2)、……、b(n)且b(i)<>b(j) (i<>j),若存在i1<i2<i3< … < ie 且有b(i1)<b(i2)< … <b(ie)则称为长度为e的不下降序列。程序要求,当原数列出之后,求出最长的不下降序列。

例如13,7,9,16,38,24,37,18,44,19,21,22,63,15。

例中13,16,18,19,21,22,63就是一个长度为7的不下降序列,

同时也有7 ,9,16,18,19,21,22,63长度为8的不下降序列。

(2)算法分析

根据动态规划的原理,由后往前进行搜索(当然从前往后也一样)。

对b(n)来说,由于它是最后一个数,所以当从b(n)开始查找时,只存在长度为1的不下降序列;

若从b(n-1)开始查找,则存在下面的两种可能性:

①若b(n-1)<b(n)则存在长度为2的不下降序列b(n-1),b(n)。

②若b(n-1)>b(n)则存在长度为1的不下降序列b(n-1)或b(n)。

一般若从b(i)开始,此时最长不下降序列应该按下列方法求出:

在b(i+1),b(i+2),…,b(n)中,找出一个比b(i)大的且最长的不下降序列,作为它的后继。

(3)代码

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class LongSubSequence {/*** 最长不下降子序列* 逆序* 含义:f[n]-从n到最后的最大长度;c[n]-存放下一个的下标* 公式:f[n] = max{f[x]} + 1;{x>n && a[n]<=a[x]}* 边界:f[a.length-1] = 1;* */public void negative(int[] a) {int length = a.length;int[] f = new int[length];int[] c = new int[length];// borderf[length-1] = 1;// formulaint i,j;for (i=length-2; i>=0; i--) {// 保存长度int l = 0;// 保存索引int k = 0;for (j=i+1; j<=length-1; j++) {if (l<f[j] && a[i]<=a[j]) {l = f[j];k = j;}}f[i] = l + 1;c[i] = k;}// resultint temp = 0;int index = 0;for (i=0; i<length; i++) {if (temp < f[i]) {temp = f[i];index = i;}}System.out.println("the long of sub sequence : " + temp);System.out.print("the sub sequence is : ");while (index != 0) {System.out.print(a[index] + " ");index = c[index];}}/*** 最长不下降子序列* 正序* 含义:f[n],从起点到当前的最大长度* 公式:f[n] = max{f[x]} + 1;{0<=x<n && a[x]<=a[n]}* 边界:f[0] = 1;* */public void positive(int[] a) {int length = a.length;int[] f = new int[length];int[] c = new int[length];// borderf[0] = 1;// formulaint i,j,l,k;for (i=1; i<length; i++) {l = 0;k = 0;for (j=0; j<i; j++) {if (l<f[j] && a[j]<=a[i]) {l = f[j];k = j;}}f[i] = l + 1;c[i] = k;}// resultint temp = 0;k = 0;for (i=0; i<length; i++) {if (temp < f[i]) {temp = f[i];k = i;}}System.out.println("the long of sub sequence : " + temp);System.out.print("the sub sequence is : ");while (k != 0) {System.out.print(a[k] + " ");k = c[k];}}public static void main(String[] args) {LongSubSequence l = new LongSubSequence();int[] a = new int[]{13,7,9,16,38,24,37,18,44,19,21,22,63,15};l.negative(a);System.out.println("");l.positive(a);}
}
</pre>

2.3 走楼梯

(1)问题描述

有 n 级台阶,一个人每次上一级或者两级,问有多少种走完 n 级台阶的方法

(2)解析

本质上是斐波那契数列问题

假设只有一个台阶,那么只有一种跳法,那就是一次跳一级,f (1)=1;如果有两个台阶,那么有两种跳法,第一种跳法是一次跳一级,第二种跳法是一次跳两级,f (2)=2。如果有大于 2 级的 n 级台阶,那么假如第一次跳一级台阶,剩下还有 n-1 级台阶,有 f (n-1) 种跳法,假如第一次条 2 级台阶,剩下 n-2 级台阶,有 f (n-2) 种跳法。这就表示 f (n)=f (n-1)+f (n-2)

(3)代码

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">/*** 有 n 级台阶,一个人每次上一级或者两级,问有多少种走完 n 级台阶的方法* 含义:f[n]-走法个数* 公式:f[n] = f[n-1] + f[n-2]* 公式代表第一步走一阶,则有f[n-1],第一步走二阶,则有f[n-2]* */public int positive(int n) {if (n == 1) {return 1;} else if (n == 2) {return 2;} else {int[] f = new int[n+1];f[1] = 1;f[2] = 2;for (int i = 3; i<=n; i++) {f[i] = f[i-1] + f[i-2];}return f[n];}}
</pre>

2.4 公共子序列

(1)问题描述

一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X=<x1,x2,…,xm>,则另一序列Z=<z1,z2,…,zk>是X的子序列是指存在一个严格递增的下标序列<i1,i2,…,ik>,使得对于所有j=1,2,…,k有:

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Xij=Zj
</pre>

例如,序列Z=<B,C,D,B>是序列X=<A,B,C,B,D,A,B>的子序列,相应的递增下标序列为<2,3,5,7>。给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。例如,若X=<A,B,C,B,D,A,B>和Y=<B,D,C,A,B,A>,则序列<B,C,A>是X和Y的一个公共子序列,序列 <B,C,B,A>也是X和Y的一个公共子序列。而且,后者是X和Y的一个最长公共子序列.因为X和Y没有长度大于4的公共子序列。

给定两个序列X=<x1,x2,…,xm>和Y=<y1,y2….yn>.要求找出X和Y的一个最长公共子序列。

(2)样例输入

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">ABCBDAB
BDCABA
</pre>

(3)样例输出

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">4
</pre>

(4)代码

<pre style="box-sizing: border-box; font-family: monospace; font-size: 18px; margin: 20px 0px; padding: 15px; border: 0px; background-color: rgb(244, 245, 246); white-space: pre-wrap; word-break: break-all; color: rgb(34, 34, 34); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">/*** @author 谢世杰*/
public class LongCommonSequence {/*** 顺序* 两个序列的最长公共子序列** 含义:f[x][y],A序列0...x 和 B序列0...y 的公共子序列最大长度** 分四种情况考虑:* 1.A[x]在公共子序列,B[y]不在,则f[x][y] = f[x][y-1]* 2.A[x]不在公共子序列,B[y]在,则f[x][y] = f[x-1][y]* 3.A[x],B[y]均在,则f[x][y] = f[x-1][y-1] + 1* 4.A[x],B[y]均不在,则f[x][y] = f[x-1][y-1]* 则 f[x][y] 取上述最大值即可,f[x-1][y-1]和f[x-1][y-1]+1 可以合并为后者** 公式:f[x][y] = max{f[x][y-1],f[x-1][y],f[x-1][y-1]+1}* 边界:f[0...x][0] = 0, f[0][0...y] = 0* */public void method(char[] a, char[] b) {int na = a.length;int nb = b.length;int[][] f = new int[na+1][nb+1];// 公式int i,j;for (i=1; i<=na; i++) {for (j=1; j<=nb; j++) {// 考虑a,b中有一个是在目标子串中f[i][j] = f[i-1][j] > f[i][j-1] ? f[i-1][j] : f[i][j-1];// 当a,b都在目标子串中if (a[i-1] == b[j-1]) {f[i][j] = (f[i-1][j-1] + 1) > f[i][j] ? (f[i-1][j-1] + 1) : f[i][j];}}}System.out.println("long = " + f[na][nb]);}public static void main(String[] args) {LongCommonSequence l = new LongCommonSequence();String a = "ABCBDAB";char[] aa = a.toCharArray();String b = "BDCABA";char[] bb = b.toCharArray();l.method(aa,bb);}
}
</pre>

看到这里的朋友们,还有更多的读者福利哦~除了上面分享的66个Java面试知识点,小编在这里还要分享一下Java架构专题的面试资料及一些大厂的面试资料,还有更多的Java架构学习资料哦(高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)

1、Java架构专题面试

(Java,spring,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx...)

2、大厂面试

BAT,天猫,蚂蚁,中兴,迅雷,网易,华为,谷歌......

3、Java架构学习资料(笔记+视频)

Java:实现动态规划的4个经典题型,你都会吗?拒绝做优秀的码农相关推荐

  1. java 品尝饮料,java细节经典题型

    28. 选项中哪一行代码可以替换题目中//add code here 而不产生编译错误?() [java] view plaincopy 1. public abstract class MyClas ...

  2. 算法(Java)——动态规划

    算法相关数据结构总结: 序号 数据结构 文章 1 动态规划 动态规划之背包问题--01背包 动态规划之背包问题--完全背包 动态规划之打家劫舍系列问题 动态规划之股票买卖系列问题 动态规划之子序列问题 ...

  3. 最值得收藏的 数据结构 全部知识点思维导图整理(王道考研), 附带经典题型整理

    本文的思维导图根据王道的数据结构书本整理而来并标记出重点内容,包括了知识点和部分课后习题 思维导图源文件已经发布在我的资源当中, 点击获取全部导图和配套OneNote笔记, 有需要的可以去 我的主页 ...

  4. 0-1背包 java_0-1背包问题,java的动态规划如题,代码如下public

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 0-1背包问题,java的动态规划 如题,代码如下 public class dongtaiguihua01 { public static void m ...

  5. pwn学习总结(五) —— 堆溢出经典题型整理

    pwn学习总结(五) -- 堆溢出经典题型整理 fastbin + 栈溢出 fastbin + 函数构造 fastbin + 堆执行 fastbin + malloc_hook fastbin + 栈 ...

  6. pwn学习总结(三) —— 栈溢出经典题型整理

    pwn学习总结(三) -- 栈溢出经典题型整理 ret2text ret2shellcode rop ret2libc 使用DynELF实现远程libc泄露 ret2syscall ret2libc ...

  7. mysql中select 的题型_MYSQL经典题型详情解析

    学完了mysql后发现有很多地方不是很明白,于是总结了mysql的经典题型,不论是工作还是面试,我相信还是有一定帮助的. 例题一 ​ 在我的数据库中数据如下(排序有些差别,但是不影响结果) ​ 分析: ...

  8. 0 1背包问题 java_0-1背包问题,java的动态规划如题,代码如下public

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 0-1背包问题,java的动态规划 如题,代码如下 public class dongtaiguihua01 { public static void m ...

  9. java数据结构-动态规划算法-一次性学会

    java数据结构-动态规划算法 算法介绍 最佳实践-背包问题 代码实践 寻找最长回文子串的求解 总结 算法介绍 动态规划算法的核心思想是:将大问题划分为小问题,一步步获取最优解 与分治算法类似,但也有 ...

  10. JavaScript中的经典题型(类数组、CSS Sprites、事件委托、经典去重、原型链、闭包、深浅克隆、附带思路流程和源码)

    JavaScript中的经典题型 一.JavaScript中的经典题型 1..如何判断一个数组和类数组? 首先要明白什么是类数组. 类数组:类数组是一个普通对象,他的原型是Object.而真实的数组是 ...

最新文章

  1. linux7.2配置多路径软件,RHEL6使用系统自带多路径软件配置多路径,rhel6路径
  2. word删除分节符后之前的格式乱了_分页符分节符,你知道多少
  3. (Portal 开发读书笔记)PortletFileUpload
  4. java中计算两日期相减方法
  5. 分享一套jquery视频教程
  6. javac 编译JavaWeb项目
  7. 常州一中训练试题泛做 Part 1
  8. 记一次简单爬虫(豆瓣/dytt)
  9. printf二进制数据
  10. 测试VPS服务器脚本,一检测VPS网络速度,硬盘性能等
  11. norflash/nandflash 启动分析 转
  12. 使用证件照api接口快速上线证件照业务-超详细!
  13. 【遇见Doris】寒冷冬日的一次温暖相聚 · Doris开发者沙龙
  14. 3次根号如何用python表达_python怎么表示根号运算
  15. Pycharm、Idea登录GitHub报错,无法连接
  16. 戴尔t420服务器显示器无信号,显示器无信号的原因及解决方法
  17. 破解Windows 2008 R2管理员密码的两种方法
  18. 使用格式工厂转换视频为MP4(AVCH264)格式
  19. 软件测试工程师 | 不拼学历,还能进大厂吗?
  20. (私人收藏)蓝色夜空背景的通用商务PPT模板

热门文章

  1. 计算机应用能力考试湖南成绩查询,湖南计算机等级考试成绩查询入口
  2. 笔记本BIOS能检测到固态,进入系统后磁盘管理不显示固态硬盘
  3. ​Copyright到底是什么意思?
  4. 户外广告牌新标准将规定字体、颜色
  5. linux清理缓存和垃圾,CentOS等Linux系统如何清理系统垃圾和日志?
  6. 计算机课安全管理制度,微机室安全管理制度.doc
  7. 任正非:一江春水向东流
  8. win10系统如何telnet服务器,win10专业版官网系统如何开启telnet服务的办法
  9. 激活Windows Vista Home Basic Aero玻璃效果
  10. RN vivo访问相册失败 warning : User cancelled image selection