关于dp数组推导过程的确定
一般情况下, 关于推导dp数组, 有两种推导思路
1 通过dp数组直接存储目的值的方式, 每一个推导都是为了求出本层的目的值 (这种情况下, 可能待存储属性具有多种状态, 但是我们只考虑其中一种状态, 这种情况之下, 往往dp数组是一维的, 数组的最后一个数据就是我们要求的目的值.
2 通过dp数组存储不同属性的不同的状态值, 这种情况下, 我们往往要考虑带存储属性的不同状态, dp数组往往是多维的, 对于dp数组的每一级的每一种状态值的确定, 都需要根据前级的多种不同状态来确定
做题时, 使用第二种思路可能会更加的容易考虑, 但是也好像会超时. 使用第一种思路, 最终获取结果可能会更容易, 不过想到题解的话好像会更难一点, 其实吧, 两种思路很相像, 只不过是自己可能考虑的不够充分或者经验不足, 才导致了一些超时的问题
例题: (LeetCode题目1143)
思路一代码:
1 public class _1143_Solution { 2 3 public int longestCommonSubsequence(String text1, String text2) { 4 5 int size1 = text1.length(); 6 int size2 = text2.length(); 7 // 首先确定dp数组的容量来源, 然后确定需要存放属性的对象实体, 然后确定需要存放属性的多种状态 8 // 确定dp数组及其下标的含义 9 int[][] dp = new int[size1+1][size2+1]; 10 // dp数组初始化 11 for (int i = 0; i <= size1; i++) { 12 dp[i][0] = 0; 13 } 14 for (int j = 0; j <= size2; j++) { 15 dp[0][j] = 0; 16 } 17 18 // 依次为dp数组赋值 19 for (int i = 1; i <= size1; i++) { 20 for (int j = 1; j <= size2; j++) { 21 22 if (text1.charAt(i - 1) == text2.charAt(j - 1)) { 23 24 dp[i][j] = dp[i-1][j-1] + 1; 25 } else { 26 dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); 27 } 28 } 29 30 // 打印dp数组, 查看结果是否符合预期 31 System.out.print("这是第" + i + "行的数据: "); 32 for (int m = 1; m <= size2; m++) { 33 System.out.print(dp[i][m] + "---"); 34 } 35 System.out.println(); 36 37 } 38 39 // 找到二维数组中的最大值 40 int max = 0; 41 for (int i = 0; i <= size1; i++) { 42 for (int j = 0; j <= size2; j++) { 43 if (dp[i][j] > max) { 44 max = dp[i][j]; 45 } 46 } 47 } 48 return max; 49 } 50 51 public static void main(String[] args) { 52 _1143_Solution solution = new _1143_Solution(); 53 System.out.println(solution.longestCommonSubsequence("abcba", "abcbcba")); 54 } 55 }
思路二代码:
1 class Solution { 2 public int longestCommonSubsequence(String text1, String text2) { 3 4 int size1 = text1.length(); 5 int size2 = text2.length(); 6 // 首先确定dp数组的容量来源, 然后确定需要存放属性的对象实体, 然后确定需要存放属性的多种状态 7 // 确定dp数组及其下标的含义 8 int[][] dp = new int[size1+1][size2+1]; 9 // dp数组初始化 10 for (int i = 0; i <= size1; i++) { 11 dp[i][0] = 0; 12 } 13 for (int j = 0; j <= size2; j++) { 14 dp[0][j] = 0; 15 } 16 17 // 依次为dp数组赋值 18 for (int i = 1; i <= size1; i++) { 19 for (int j = 1; j <= size2; j++) { 20 21 if (text1.charAt(i - 1) == text2.charAt(j - 1)) { 22 // 找到这两个之前的最大值, 然后加一 23 int max = 0; 24 for (int m = 0; m < i; m++) { 25 for (int n = 0; n < j; n++) { 26 if (dp[m][n] > max) { 27 max = dp[m][n]; 28 } 29 } 30 } 31 dp[i][j] = max+1; 32 } else { 33 dp[i][j] = 0; 34 } 35 } 36 37 38 } 39 40 // 找到二维数组中的最大值 41 int max = 0; 42 for (int i = 0; i <= size1; i++) { 43 for (int j = 0; j <= size2; j++) { 44 if (dp[i][j] > max) { 45 max = dp[i][j]; 46 } 47 } 48 } 49 return max; 50 } 51 }