LongestCommonSubstring 最长公共子串
动态规划解法:
dp[i][j]表示以si和tj结尾的公共子串的最大长度;
则转移方程为:
dp[i][j] = si == tj ? 1 : 0 , i==0||j==0
dp[i][j] = s1[i] == s2[j] ? dp[i-1][j-1]+1 : 0 ,other
CODE
1 | /** |
NOTE
輸出最大子串:记录最大子串值和位置,沿对角线遍历(–1;–j),因为子串是连续的正确路径只会是对角线
LongesetCommonSubsequence 最长公共子序列
动态规划解法:
dp[i][j]表示s0…si与t0…tj最长公共子序列
转移方程:
dp[i][j] = s[i]== t[j] ? 1 : 0, i==0 and j==0;
dp[i][j] = s[i]== t[j] ? 1 : dp[i == 0 ? 0 : i - 1][j == 0 ? 0 : j - 1],i==0 or j==0 and i!=j;
dp[i][j] = dp[i-1][j-1] + 1, s[i] == t[j];
dp[i][j] = max(dp[i-1][j], dp[i][j-1]), s[i] != t[j];
CODE:
1 | public static int LongestCommonSubsequence (String s1, String s2) { |
NOTE:关于输出,从dp表最后一位开始遍历,若相对的字符相等则添加,遍历–i与–j,若不等,比较–i,j与i,–j大小,遍历大者,
若相等(搞清楚后补充)。。。
LIS 最长非递减序列
动态规划解法:
dp[i]表示里nums[i]为结尾的lis
转移方程:
dp[i] = max(dp[i],d[j]+1),s[j]<=s[i]
CODE:
1 | public static int LIS(int[] nums) { |
贪心+二分:
贪心:使得加入最后一位的值尽可能的小,这样序列才更容易增加
二分:搜索当前添加元素在已添加数组的下边界(加入的位置,数组都是排好序的)
将元素加入res数组,如果带加入的数字大于res数组的最后一位,则直接添加,否则二分查找要替换的位置,最后res数组大小即为结果(注意res数组内容并不是要求数列)
CODE:
1 | /** |