二维int数组矩阵从左上角到右上角的最短路径
public static int minPathSum1(int[][] m) {
if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
return 0;
}
int row = m.length;
int col = m[0].length;
int[][] dp = new int[row][col];
dp[0][0] = m[0][0];
for (int i = 1; i < row; i++) {
dp[i][0] = dp[i - 1][0] + m[i][0];
}
for (int j = 1; j < col; j++) {
dp[0][j] = dp[0][j - 1] + m[0][j];
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + m[i][j];
}
}
return dp[row - 1][col - 1];
}
分割整数n,若干个数的和为n,求若干个数的最大乘积。
public int integerBreak(int n) {
int[] dp = new int[n + 1];
dp[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i - 1; j++) {
dp[i] = Math.max(dp[i], Math.max(j * dp[i - j], j * (i - j)));
}
}
return dp[n];
}
最长公共子序列的长度
public int lengthOfLCS(int[] nums1, int[] nums2) {
int n1 = nums1.length, n2 = nums2.length;
int[][] dp = new int[n1 + 1][n2 + 1];
for (int i = 1; i <= n1; i++) {
for (int j = 1; j <= n2; j++) {
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[n1][n2];
}
输出最长公共子序列
public static String lcse(String str1, String str2) {
if (str1 == null || str2 == null || str1.equals("") || str2.equals("")) {
return "";
}
char[] chs1 = str1.toCharArray();
char[] chs2 = str2.toCharArray();
int[][] dp = getdp(chs1, chs2);
int m = chs1.length - 1;
int n = chs2.length - 1;
char[] res = new char[dp[m][n]];
int index = res.length - 1;
while (index >= 0) {
if (n > 0 && dp[m][n] == dp[m][n - 1]) {
n--;
} else if (m > 0 && dp[m][n] == dp[m - 1][n]) {
m--;
} else {
res[index--] = chs1[m];
m--;
n--;
}
}
return String.valueOf(res);
}
public static int[][] getdp(char[] str1, char[] str2) {
int[][] dp = new int[str1.length][str2.length];
dp[0][0] = str1[0] == str2[0] ? 1 : 0;
for (int i = 1; i < str1.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], str1[i] == str2[0] ? 1 : 0);
}
for (int j = 1; j < str2.length; j++) {
dp[0][j] = Math.max(dp[0][j - 1], str1[0] == str2[j] ? 1 : 0);
}
for (int i = 1; i < str1.length; i++) {
for (int j = 1; j < str2.length; j++) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
if (str1[i] == str2[j]) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + 1);
}
}
}
return dp;
}
换钱的最少硬币数,举例 arr =[5,2,3],aim = 20, 4张5元可以凑够20元,故最少货币数位4
public static int minCoins(int[] arr, int aim) {
if (arr == null || arr.length == 0 || aim < 0) {
return -1;
}
int n = arr.length;
int max = Integer.MAX_VALUE;
int[][] dp = new int[n][aim + 1];
for (int j = 1; j <= aim; j++) {
dp[0][j] = max;
if (j - arr[0] >= 0 && dp[0][j - arr[0]] != max) {
dp[0][j] = dp[0][j - arr[0]] + 1;
}
}
int left = 0;
for (int i = 1; i < n; i++) {
for (int j = 1; j <= aim; j++) {
left = max;
if (j - arr[i] >= 0 && dp[i][j - arr[i]] != max) {
left = dp[i][j - arr[i]] + 1;
}
dp[i][j] = Math.min(left, dp[i - 1][j]);
}
}
return dp[n - 1][aim] != max ? dp[n - 1][aim] : -1;
}