modify code

pull/6/head
左程云 4 years ago
parent 355cdbd84f
commit 8f754ac742

@ -1,38 +1,75 @@
package class19;
// 测试链接https://leetcode.com/problems/longest-palindromic-subsequence/
public class Code02_PalindromeSubsequence {
public static int lcse(char[] str1, char[] str2) {
int[][] dp = new int[str1.length][str2.length];
public static int longestPalindromeSubseq1(String s) {
if (s == null || s.length() == 0) {
return 0;
}
if (s.length() == 1) {
return 1;
}
char[] str = s.toCharArray();
char[] reverse = reverse(str);
return longestCommonSubsequence(str, reverse);
}
public static char[] reverse(char[] str) {
int N = str.length;
char[] reverse = new char[str.length];
for (int i = 0; i < str.length; i++) {
reverse[--N] = str[i];
}
return reverse;
}
public static int longestCommonSubsequence(char[] str1, char[] str2) {
int N = str1.length;
int M = str2.length;
int[][] dp = new int[N][M];
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 i = 1; i < N; i++) {
dp[i][0] = str1[i] == str2[0] ? 1 : dp[i - 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 j = 1; j < M; j++) {
dp[0][j] = str1[0] == str2[j] ? 1 : dp[0][j - 1];
}
for (int i = 1; i < str1.length; i++) {
for (int j = 1; j < str2.length; j++) {
for (int i = 1; i < N; i++) {
for (int j = 1; j < M; 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[str1.length - 1][str2.length - 1];
return dp[N - 1][M - 1];
}
public static void main(String[] args) {
public static int longestPalindromeSubseq2(String s) {
if (s == null || s.length() == 0) {
return 0;
}
if (s.length() == 1) {
return 1;
}
char[] str = s.toCharArray();
int N = str.length;
int[][] dp = new int[N][N];
dp[N - 1][N - 1] = 1;
for (int i = 0; i < N - 1; i++) {
dp[i][i] = 1;
dp[i][i + 1] = str[i] == str[i + 1] ? 2 : 1;
}
for (int i = N - 3; i >= 0; i--) {
for (int j = i + 2; j < N; j++) {
dp[i][j] = Math.max(dp[i][j - 1], dp[i + 1][j]);
if (str[i] == str[j]) {
dp[i][j] = Math.max(dp[i][j], dp[i + 1][j - 1] + 2);
}
}
}
return dp[0][N - 1];
}
}

@ -2,15 +2,10 @@ package class19;
public class Code03_HorseJump {
// 10*9
// 0~9 y
// 0~8 x
public static int ways(int a, int b, int step) {
return f(0, 0, step, a, b);
}
// 马在(i,j)位置还有step步要去跳
// 返回最终来到(a,b)的方法数
public static int f(int i, int j, int step, int a, int b) {
if (i < 0 || i > 9 || j < 0 || j > 8) {
return 0;
@ -31,7 +26,6 @@ public class Code03_HorseJump {
public static int waysdp(int a, int b, int s) {
// (i,j,0~ step)
int[][][] dp = new int[10][9][s+1];
dp[a][b][0] = 1;
for(int step = 1 ; step <= s;step++ ) { // 按层来

@ -1,8 +1,5 @@
package class20;
// arr是货币数组其中的值都是正数每个值都认为是一张货币
// 即便是值相同的货币认为每一张都是独立且不同的,
// 返回组成aim的方法数
public class Code01_CoinsWayEveryPaperDifferent {
public static int coinWays(int[] arr, int aim) {
@ -64,7 +61,7 @@ public class Code01_CoinsWayEveryPaperDifferent {
int aim = (int) (Math.random() * maxValue);
int ans1 = coinWays(arr, aim);
int ans2 = dp(arr, aim);
if (ans1 == ans2) {
if (ans1 != ans2) {
System.out.println("Oops!");
printArray(arr);
System.out.println(aim);

@ -1,7 +1,5 @@
package class20;
// arr是面值数组其中的值都是正数且无重复值
// 每张面值可以用无限张返回组成aim的方法数
public class Code02_CoinsWayNoLimit {
public static int coinsWay(int[] arr, int aim) {

@ -3,9 +3,6 @@ package class20;
import java.util.HashMap;
import java.util.Map.Entry;
// arr是货币数组其中的值都是正数每个值都认为是一张货币
// 值相同的货币认为每一张都没有不同!
// 返回组成aim的方法数
public class Code03_CoinsWaySameValueSamePapper {
public static class Info {

@ -4,8 +4,6 @@ import java.util.HashMap;
import java.util.Map.Entry;
import java.util.LinkedList;
// arr中的每个值都代表一张钱
// arr中都是正数aim>=0返回组成aim的最小张数
public class Code04_MinCoinsOnePaper {
public static int minCoins(int[] arr, int aim) {

@ -1,7 +1,5 @@
package class20;
// arr是面值数组其中的值都是正数且无重复值
// 每张面值可以用无限张返回组成aim的最少货币数
public class Code05_MinCoinsNoLimit {
public static int minCoins(int[] arr, int aim) {

@ -1,6 +1,5 @@
package class21;
// 题目描述看包里KillMonster.jpeg
public class Code02_KillMonster {
public static double right1(int N, int M, int K) {

@ -2,12 +2,6 @@ package class21;
import java.util.TreeSet;
/*
* arrarr
*
* 便arr
*
* */
public class Code03_SplitSumClosed {
public static int right(int[] arr) {

@ -2,15 +2,6 @@ package class21;
import java.util.TreeSet;
/*
* arrarr
* arr
* arr
*
*
* 便arr
*
* */
public class Code04_SplitSumClosedSizeHalf {
public static int right(int[] arr) {

@ -6,26 +6,16 @@ public class Code05_NQueens {
if (n < 1) {
return 0;
}
// record[0] ? record[1] ? record[2]
int[] record = new int[n]; // record[i] -> i行的皇后放在了第几列
int[] record = new int[n];
return process1(0, record, n);
}
// 潜台词record[0..i-1]的皇后,任何两个皇后一定都不共行、不共列,不共斜线
// 目前来到了第i行
// record[0..i-1]表示之前的行,放了的皇后位置
// n代表整体一共有多少行 0~n-1行
// 返回值是,摆完所有的皇后,合理的摆法有多少种
public static int process1(int i, int[] record, int n) {
if (i == n) { // 终止行
if (i == n) {
return 1;
}
// 没有到终止位置,还有皇后要摆
int res = 0;
for (int j = 0; j < n; j++) { // 当前行在i行尝试i行所有的列 -> j
// 当前i行的皇后放在j列会不会和之前(0..i-1)的皇后,不共行共列或者共斜线,
// 如果是,认为有效
// 如果不是,认为无效
for (int j = 0; j < n; j++) {
if (isValid(record, i, j)) {
record[i] = j;
res += process1(i + 1, record, n);
@ -34,11 +24,8 @@ public class Code05_NQueens {
return res;
}
// record[0..i-1]你需要看record[i...]不需要看
// 返回i行皇后放在了j列是否有效
public static boolean isValid(int[] record, int i, int j) {
for (int k = 0; k < i; k++) { // 之前的某个k行的皇后
// k, record[k] i, j
for (int k = 0; k < i; k++) {
if (j == record[k] || Math.abs(record[k] - j) == Math.abs(i - k)) {
return false;
}
@ -56,27 +43,18 @@ public class Code05_NQueens {
return process2(limit, 0, 0, 0);
}
// limit 划定了问题的规模 -> 固定
// colLim 列的限制1的位置不能放皇后0的位置可以
// leftDiaLim 左斜线的限制1的位置不能放皇后0的位置可以
// rightDiaLim 右斜线的限制1的位置不能放皇后0的位置可以
public static int process2(
int limit,
int colLim,
int leftDiaLim,
int rightDiaLim) {
if (colLim == limit) { // base case
if (colLim == limit) {
return 1;
}
// 所有可以放皇后的位置都在pos上
// colLim | leftDiaLim | rightDiaLim -> 总限制
// ~ (colLim | leftDiaLim | rightDiaLim) -> 左侧的一坨0干扰右侧每个1可尝试
int pos = limit & ( ~(colLim | leftDiaLim | rightDiaLim) );
int mostRightOne = 0;
int res = 0;
while (pos != 0) {
// 其取出pos中最右侧的1来剩下位置都是0
mostRightOne = pos & (~pos + 1);
pos = pos - mostRightOne;
res += process2(limit,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Loading…
Cancel
Save