parent
b0ec4db667
commit
4184f32000
@ -0,0 +1,41 @@
|
|||||||
|
package class38;
|
||||||
|
|
||||||
|
public class Code03_MSumToN {
|
||||||
|
|
||||||
|
public static boolean isMSum1(int num) {
|
||||||
|
for (int i = 1; i <= num; i++) {
|
||||||
|
int sum = i;
|
||||||
|
for (int j = i + 1; j <= num; j++) {
|
||||||
|
if (sum + j > num) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sum + j == num) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
sum += j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMSum2(int num) {
|
||||||
|
if (num < 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (num & (num - 1)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
for (int num = 1; num < 200; num++) {
|
||||||
|
System.out.println(num + " : " + isMSum1(num));
|
||||||
|
}
|
||||||
|
System.out.println("test begin");
|
||||||
|
for (int num = 1; num < 5000; num++) {
|
||||||
|
if (isMSum1(num) != isMSum2(num)) {
|
||||||
|
System.out.println("Oops!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("test end");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package class39;
|
||||||
|
|
||||||
|
public class Code01_DifferentBTNum {
|
||||||
|
|
||||||
|
// k(0) = 1, k(1) = 1
|
||||||
|
//
|
||||||
|
// k(n) = k(0) * k(n - 1) + k(1) * k(n - 2) + ... + k(n - 2) * k(1) + k(n - 1) * k(0)
|
||||||
|
// 或者
|
||||||
|
// k(n) = c(2n, n) / (n + 1)
|
||||||
|
// 或者
|
||||||
|
// k(n) = c(2n, n) - c(2n, n-1)
|
||||||
|
|
||||||
|
public static long num1(int N) {
|
||||||
|
if (N < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (N < 2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
long[] dp = new long[N + 1];
|
||||||
|
dp[0] = 1;
|
||||||
|
dp[1] = 1;
|
||||||
|
for (int i = 2; i <= N; i++) {
|
||||||
|
for (int leftSize = 0; leftSize < i; leftSize++) {
|
||||||
|
dp[i] += dp[leftSize] * dp[i - 1 - leftSize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[N];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long num2(int N) {
|
||||||
|
if (N < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (N < 2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
long a = 1;
|
||||||
|
long b = 1;
|
||||||
|
for (int i = 1, j = N + 1; i <= N; i++, j++) {
|
||||||
|
a *= i;
|
||||||
|
b *= j;
|
||||||
|
long gcd = gcd(a, b);
|
||||||
|
a /= gcd;
|
||||||
|
b /= gcd;
|
||||||
|
}
|
||||||
|
return (b / a) / (N + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long gcd(long m, long n) {
|
||||||
|
return n == 0 ? m : gcd(n, m % n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("test begin");
|
||||||
|
for (int i = 0; i < 15; i++) {
|
||||||
|
long ans1 = num1(i);
|
||||||
|
long ans2 = num2(i);
|
||||||
|
if (ans1 != ans2) {
|
||||||
|
System.out.println("Oops!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("test finish");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
package class39;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class Code02_10Ways {
|
||||||
|
|
||||||
|
public static long ways1(int N) {
|
||||||
|
int zero = N;
|
||||||
|
int one = N;
|
||||||
|
LinkedList<Integer> path = new LinkedList<>();
|
||||||
|
LinkedList<LinkedList<Integer>> ans = new LinkedList<>();
|
||||||
|
process(zero, one, path, ans);
|
||||||
|
long count = 0;
|
||||||
|
for (LinkedList<Integer> cur : ans) {
|
||||||
|
int status = 0;
|
||||||
|
for (Integer num : cur) {
|
||||||
|
if (num == 0) {
|
||||||
|
status++;
|
||||||
|
} else {
|
||||||
|
status--;
|
||||||
|
}
|
||||||
|
if (status < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (status == 0) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void process(int zero, int one, LinkedList<Integer> path, LinkedList<LinkedList<Integer>> ans) {
|
||||||
|
if (zero == 0 && one == 0) {
|
||||||
|
LinkedList<Integer> cur = new LinkedList<>();
|
||||||
|
for (Integer num : path) {
|
||||||
|
cur.add(num);
|
||||||
|
}
|
||||||
|
ans.add(cur);
|
||||||
|
} else {
|
||||||
|
if (zero == 0) {
|
||||||
|
path.addLast(1);
|
||||||
|
process(zero, one - 1, path, ans);
|
||||||
|
path.removeLast();
|
||||||
|
} else if (one == 0) {
|
||||||
|
path.addLast(0);
|
||||||
|
process(zero - 1, one, path, ans);
|
||||||
|
path.removeLast();
|
||||||
|
} else {
|
||||||
|
path.addLast(1);
|
||||||
|
process(zero, one - 1, path, ans);
|
||||||
|
path.removeLast();
|
||||||
|
path.addLast(0);
|
||||||
|
process(zero - 1, one, path, ans);
|
||||||
|
path.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long ways2(int N) {
|
||||||
|
if (N < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (N < 2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
long a = 1;
|
||||||
|
long b = 1;
|
||||||
|
long limit = N << 1;
|
||||||
|
for (long i = 1; i <= limit; i++) {
|
||||||
|
if (i <= N) {
|
||||||
|
a *= i;
|
||||||
|
} else {
|
||||||
|
b *= i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (b / a) / (N + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("test begin");
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
long ans1 = ways1(i);
|
||||||
|
long ans2 = ways2(i);
|
||||||
|
if (ans1 != ans2) {
|
||||||
|
System.out.println("Oops!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("test finish");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package class39;
|
||||||
|
|
||||||
|
public class Code03_RotateMatrix {
|
||||||
|
|
||||||
|
public static void rotate(int[][] matrix) {
|
||||||
|
int a = 0;
|
||||||
|
int b = 0;
|
||||||
|
int c = matrix.length - 1;
|
||||||
|
int d = matrix[0].length - 1;
|
||||||
|
while (a < c) {
|
||||||
|
rotateEdge(matrix, a++, b++, c--, d--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void rotateEdge(int[][] m, int a, int b, int c, int d) {
|
||||||
|
int tmp = 0;
|
||||||
|
for (int i = 0; i < d - b; i++) {
|
||||||
|
tmp = m[a][b + i];
|
||||||
|
m[a][b + i] = m[c - i][b];
|
||||||
|
m[c - i][b] = m[c][d - i];
|
||||||
|
m[c][d - i] = m[a + i][d];
|
||||||
|
m[a + i][d] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printMatrix(int[][] matrix) {
|
||||||
|
for (int i = 0; i != matrix.length; i++) {
|
||||||
|
for (int j = 0; j != matrix[0].length; j++) {
|
||||||
|
System.out.print(matrix[i][j] + " ");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
|
||||||
|
printMatrix(matrix);
|
||||||
|
rotate(matrix);
|
||||||
|
System.out.println("=========");
|
||||||
|
printMatrix(matrix);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package class39;
|
||||||
|
|
||||||
|
public class Code04_PrintMatrixSpiralOrder {
|
||||||
|
|
||||||
|
public static void spiralOrderPrint(int[][] matrix) {
|
||||||
|
int tR = 0;
|
||||||
|
int tC = 0;
|
||||||
|
int dR = matrix.length - 1;
|
||||||
|
int dC = matrix[0].length - 1;
|
||||||
|
while (tR <= dR && tC <= dC) {
|
||||||
|
printEdge(matrix, tR++, tC++, dR--, dC--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printEdge(int[][] m, int tR, int tC, int dR, int dC) {
|
||||||
|
if (tR == dR) {
|
||||||
|
for (int i = tC; i <= dC; i++) {
|
||||||
|
System.out.print(m[tR][i] + " ");
|
||||||
|
}
|
||||||
|
} else if (tC == dC) {
|
||||||
|
for (int i = tR; i <= dR; i++) {
|
||||||
|
System.out.print(m[i][tC] + " ");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int curC = tC;
|
||||||
|
int curR = tR;
|
||||||
|
while (curC != dC) {
|
||||||
|
System.out.print(m[tR][curC] + " ");
|
||||||
|
curC++;
|
||||||
|
}
|
||||||
|
while (curR != dR) {
|
||||||
|
System.out.print(m[curR][dC] + " ");
|
||||||
|
curR++;
|
||||||
|
}
|
||||||
|
while (curC != tC) {
|
||||||
|
System.out.print(m[dR][curC] + " ");
|
||||||
|
curC--;
|
||||||
|
}
|
||||||
|
while (curR != tR) {
|
||||||
|
System.out.print(m[curR][tC] + " ");
|
||||||
|
curR--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 },
|
||||||
|
{ 13, 14, 15, 16 } };
|
||||||
|
spiralOrderPrint(matrix);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package class39;
|
||||||
|
|
||||||
|
public class Code05_ZigZagPrintMatrix {
|
||||||
|
|
||||||
|
public static void printMatrixZigZag(int[][] matrix) {
|
||||||
|
int tR = 0;
|
||||||
|
int tC = 0;
|
||||||
|
int dR = 0;
|
||||||
|
int dC = 0;
|
||||||
|
int endR = matrix.length - 1;
|
||||||
|
int endC = matrix[0].length - 1;
|
||||||
|
boolean fromUp = false;
|
||||||
|
while (tR != endR + 1) {
|
||||||
|
printLevel(matrix, tR, tC, dR, dC, fromUp);
|
||||||
|
tR = tC == endC ? tR + 1 : tR;
|
||||||
|
tC = tC == endC ? tC : tC + 1;
|
||||||
|
dC = dR == endR ? dC + 1 : dC;
|
||||||
|
dR = dR == endR ? dR : dR + 1;
|
||||||
|
fromUp = !fromUp;
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printLevel(int[][] m, int tR, int tC, int dR, int dC,
|
||||||
|
boolean f) {
|
||||||
|
if (f) {
|
||||||
|
while (tR != dR + 1) {
|
||||||
|
System.out.print(m[tR++][tC--] + " ");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (dR != tR - 1) {
|
||||||
|
System.out.print(m[dR--][dC++] + " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
|
||||||
|
printMatrixZigZag(matrix);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package class39;
|
||||||
|
|
||||||
|
public class Code06_PrintStar {
|
||||||
|
|
||||||
|
public static void printStar(int N) {
|
||||||
|
int leftUp = 0;
|
||||||
|
int rightDown = N - 1;
|
||||||
|
char[][] m = new char[N][N];
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
for (int j = 0; j < N; j++) {
|
||||||
|
m[i][j] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (leftUp <= rightDown) {
|
||||||
|
set(m, leftUp, rightDown);
|
||||||
|
leftUp += 2;
|
||||||
|
rightDown -= 2;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
for (int j = 0; j < N; j++) {
|
||||||
|
System.out.print(m[i][j] + " ");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void set(char[][] m, int leftUp, int rightDown) {
|
||||||
|
for (int col = leftUp; col <= rightDown; col++) {
|
||||||
|
m[leftUp][col] = '*';
|
||||||
|
}
|
||||||
|
for (int row = leftUp + 1; row <= rightDown; row++) {
|
||||||
|
m[row][rightDown] = '*';
|
||||||
|
}
|
||||||
|
for (int col = rightDown - 1; col > leftUp; col--) {
|
||||||
|
m[rightDown][col] = '*';
|
||||||
|
}
|
||||||
|
for (int row = rightDown - 1; row > leftUp + 1; row--) {
|
||||||
|
m[row][leftUp + 1] = '*';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
printStar(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package class40;
|
||||||
|
|
||||||
|
public class Code01_LongestSumSubArrayLengthInPositiveArray {
|
||||||
|
|
||||||
|
public static int getMaxLength(int[] arr, int K) {
|
||||||
|
if (arr == null || arr.length == 0 || K <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int left = 0;
|
||||||
|
int right = 0;
|
||||||
|
int sum = arr[0];
|
||||||
|
int len = 0;
|
||||||
|
while (right < arr.length) {
|
||||||
|
if (sum == K) {
|
||||||
|
len = Math.max(len, right - left + 1);
|
||||||
|
sum -= arr[left++];
|
||||||
|
} else if (sum < K) {
|
||||||
|
right++;
|
||||||
|
if (right == arr.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sum += arr[right];
|
||||||
|
} else {
|
||||||
|
sum -= arr[left++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static int right(int[] arr, int K) {
|
||||||
|
int max = 0;
|
||||||
|
for (int i = 0; i < arr.length; i++) {
|
||||||
|
for (int j = i; j < arr.length; j++) {
|
||||||
|
if (valid(arr, i, j, K)) {
|
||||||
|
max = Math.max(max, j - i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static boolean valid(int[] arr, int L, int R, int K) {
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = L; i <= R; i++) {
|
||||||
|
sum += arr[i];
|
||||||
|
}
|
||||||
|
return sum == K;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static int[] generatePositiveArray(int size, int value) {
|
||||||
|
int[] ans = new int[size];
|
||||||
|
for (int i = 0; i != size; i++) {
|
||||||
|
ans[i] = (int) (Math.random() * value) + 1;
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static void printArray(int[] arr) {
|
||||||
|
for (int i = 0; i != arr.length; i++) {
|
||||||
|
System.out.print(arr[i] + " ");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int len = 50;
|
||||||
|
int value = 100;
|
||||||
|
int testTime = 500000;
|
||||||
|
System.out.println("test begin");
|
||||||
|
for (int i = 0; i < testTime; i++) {
|
||||||
|
int[] arr = generatePositiveArray(len, value);
|
||||||
|
int K = (int) (Math.random() * value) + 1;
|
||||||
|
int ans1 = getMaxLength(arr, K);
|
||||||
|
int ans2 = right(arr, K);
|
||||||
|
if (ans1 != ans2) {
|
||||||
|
System.out.println("Oops!");
|
||||||
|
printArray(arr);
|
||||||
|
System.out.println("K : " + K);
|
||||||
|
System.out.println(ans1);
|
||||||
|
System.out.println(ans2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("test end");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
package class40;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Code02_LongestSumSubArrayLength {
|
||||||
|
|
||||||
|
public static int maxLength(int[] arr, int k) {
|
||||||
|
if (arr == null || arr.length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
|
||||||
|
map.put(0, -1); // important
|
||||||
|
int len = 0;
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < arr.length; i++) {
|
||||||
|
sum += arr[i];
|
||||||
|
if (map.containsKey(sum - k)) {
|
||||||
|
len = Math.max(i - map.get(sum - k), len);
|
||||||
|
}
|
||||||
|
if (!map.containsKey(sum)) {
|
||||||
|
map.put(sum, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static int right(int[] arr, int K) {
|
||||||
|
int max = 0;
|
||||||
|
for (int i = 0; i < arr.length; i++) {
|
||||||
|
for (int j = i; j < arr.length; j++) {
|
||||||
|
if (valid(arr, i, j, K)) {
|
||||||
|
max = Math.max(max, j - i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static boolean valid(int[] arr, int L, int R, int K) {
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = L; i <= R; i++) {
|
||||||
|
sum += arr[i];
|
||||||
|
}
|
||||||
|
return sum == K;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static int[] generateRandomArray(int size, int value) {
|
||||||
|
int[] ans = new int[(int) (Math.random() * size) + 1];
|
||||||
|
for (int i = 0; i < ans.length; i++) {
|
||||||
|
ans[i] = (int) (Math.random() * value) - (int) (Math.random() * value);
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static void printArray(int[] arr) {
|
||||||
|
for (int i = 0; i != arr.length; i++) {
|
||||||
|
System.out.print(arr[i] + " ");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int len = 50;
|
||||||
|
int value = 100;
|
||||||
|
int testTime = 500000;
|
||||||
|
|
||||||
|
System.out.println("test begin");
|
||||||
|
for (int i = 0; i < testTime; i++) {
|
||||||
|
int[] arr = generateRandomArray(len, value);
|
||||||
|
int K = (int) (Math.random() * value) - (int) (Math.random() * value);
|
||||||
|
int ans1 = maxLength(arr, K);
|
||||||
|
int ans2 = right(arr, K);
|
||||||
|
if (ans1 != ans2) {
|
||||||
|
System.out.println("Oops!");
|
||||||
|
printArray(arr);
|
||||||
|
System.out.println("K : " + K);
|
||||||
|
System.out.println(ans1);
|
||||||
|
System.out.println(ans2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("test end");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,124 @@
|
|||||||
|
package class41;
|
||||||
|
|
||||||
|
public class Code02_SplitArrayLargestSum {
|
||||||
|
|
||||||
|
public static int splitArray1(int[] nums, int m) {
|
||||||
|
return process(nums, 0, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int process(int[] arr, int index, int part) {
|
||||||
|
if (index == arr.length) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (part == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int first = 0;
|
||||||
|
int min = Integer.MAX_VALUE;
|
||||||
|
for (int end = index; arr.length - end >= part; end++) {
|
||||||
|
first += arr[end];
|
||||||
|
int next = process(arr, end + 1, part - 1);
|
||||||
|
if (next != -1) {
|
||||||
|
min = Math.min(min, Math.max(first, next));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int splitArray2(int[] nums, int M) {
|
||||||
|
int N = nums.length;
|
||||||
|
int[] help = new int[nums.length + 1];
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
help[i + 1] = help[i] + nums[i];
|
||||||
|
}
|
||||||
|
int[][] dp = new int[N][M + 1];
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
dp[i][1] = help[i + 1] - help[0];
|
||||||
|
}
|
||||||
|
for (int i = 1; i < Math.min(N, M); i++) {
|
||||||
|
dp[i][i + 1] = Math.max(dp[i - 1][i], nums[i]);
|
||||||
|
}
|
||||||
|
for (int i = 2; i < N; i++) {
|
||||||
|
for (int j = 2; j <= Math.min(i, M); j++) {
|
||||||
|
dp[i][j] = Integer.MAX_VALUE;
|
||||||
|
for (int k = i; k >= j - 1; k--) {
|
||||||
|
dp[i][j] = Math.min(dp[i][j], Math.max(dp[k - 1][j - 1], help[i + 1] - help[k]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[N - 1][M];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int splitArray3(int[] nums, int M) {
|
||||||
|
int N = nums.length;
|
||||||
|
int[] help = new int[nums.length + 1];
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
help[i + 1] = help[i] + nums[i];
|
||||||
|
}
|
||||||
|
int[][] dp = new int[N][M + 1];
|
||||||
|
int[][] best = new int[N][M + 1];
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
dp[i][1] = help[i + 1] - help[0];
|
||||||
|
}
|
||||||
|
for (int i = 1; i < Math.min(N, M); i++) {
|
||||||
|
dp[i][i + 1] = Math.max(dp[i - 1][i], nums[i]);
|
||||||
|
best[i][i + 1] = i;
|
||||||
|
}
|
||||||
|
for (int i = 2; i < N; i++) {
|
||||||
|
for (int j = Math.min(i, M); j >= 2; j--) {
|
||||||
|
dp[i][j] = Integer.MAX_VALUE;
|
||||||
|
int left = best[i - 1][j];
|
||||||
|
int right = j + 1 > M ? i : best[i][j + 1];
|
||||||
|
for (int k = left; k <= right; k++) {
|
||||||
|
int curAns = Math.max(dp[k - 1][j - 1], help[i + 1] - help[k]);
|
||||||
|
if (dp[i][j] > curAns) {
|
||||||
|
dp[i][j] = curAns;
|
||||||
|
best[i][j] = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[N - 1][M];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int splitArray4(int[] nums, int M) {
|
||||||
|
long sum = 0;
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
sum += nums[i];
|
||||||
|
}
|
||||||
|
long l = 0;
|
||||||
|
long r = sum;
|
||||||
|
long ans = 0;
|
||||||
|
while (l <= r) {
|
||||||
|
long mid = (l + r) / 2;
|
||||||
|
long cur = getNeedParts(nums, mid);
|
||||||
|
if (cur <= M) {
|
||||||
|
ans = mid;
|
||||||
|
r = mid - 1;
|
||||||
|
} else {
|
||||||
|
l = mid + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (int) ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getNeedParts(int[] arr, long aim) {
|
||||||
|
for (int i = 0; i < arr.length; i++) {
|
||||||
|
if (arr[i] > aim) {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int parts = 1;
|
||||||
|
int all = arr[0];
|
||||||
|
for (int i = 1; i < arr.length; i++) {
|
||||||
|
if (all + arr[i] > aim) {
|
||||||
|
parts++;
|
||||||
|
all = arr[i];
|
||||||
|
} else {
|
||||||
|
all += arr[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,148 @@
|
|||||||
|
package class44;
|
||||||
|
|
||||||
|
// 测试链接: https://leetcode.com/problems/last-substring-in-lexicographical-order/
|
||||||
|
public class Code02_LastSubstringInLexicographicalOrder {
|
||||||
|
|
||||||
|
public static String lastSubstring(String s) {
|
||||||
|
if (s == null || s.length() == 0) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
int N = s.length();
|
||||||
|
char[] str = s.toCharArray();
|
||||||
|
int min = Integer.MAX_VALUE;
|
||||||
|
int max = Integer.MIN_VALUE;
|
||||||
|
for (char cha : str) {
|
||||||
|
min = Math.min(min, cha);
|
||||||
|
max = Math.max(max, cha);
|
||||||
|
}
|
||||||
|
int[] arr = new int[N];
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
arr[i] = str[i] - min + 1;
|
||||||
|
}
|
||||||
|
DC3 dc3 = new DC3(arr, max - min + 1);
|
||||||
|
return s.substring(dc3.sa[N - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DC3 {
|
||||||
|
|
||||||
|
public int[] sa;
|
||||||
|
|
||||||
|
public int[] rank;
|
||||||
|
|
||||||
|
public DC3(int[] nums, int max) {
|
||||||
|
sa = sa(nums, max);
|
||||||
|
rank = rank();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] sa(int[] nums, int max) {
|
||||||
|
int n = nums.length;
|
||||||
|
int[] arr = new int[n + 3];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
arr[i] = nums[i];
|
||||||
|
}
|
||||||
|
return skew(arr, n, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] skew(int[] nums, int n, int K) {
|
||||||
|
int n0 = (n + 2) / 3, n1 = (n + 1) / 3, n2 = n / 3, n02 = n0 + n2;
|
||||||
|
int[] s12 = new int[n02 + 3], sa12 = new int[n02 + 3];
|
||||||
|
for (int i = 0, j = 0; i < n + (n0 - n1); ++i) {
|
||||||
|
if (0 != i % 3) {
|
||||||
|
s12[j++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radixPass(nums, s12, sa12, 2, n02, K);
|
||||||
|
radixPass(nums, sa12, s12, 1, n02, K);
|
||||||
|
radixPass(nums, s12, sa12, 0, n02, K);
|
||||||
|
int name = 0, c0 = -1, c1 = -1, c2 = -1;
|
||||||
|
for (int i = 0; i < n02; ++i) {
|
||||||
|
if (c0 != nums[sa12[i]] || c1 != nums[sa12[i] + 1] || c2 != nums[sa12[i] + 2]) {
|
||||||
|
name++;
|
||||||
|
c0 = nums[sa12[i]];
|
||||||
|
c1 = nums[sa12[i] + 1];
|
||||||
|
c2 = nums[sa12[i] + 2];
|
||||||
|
}
|
||||||
|
if (1 == sa12[i] % 3) {
|
||||||
|
s12[sa12[i] / 3] = name;
|
||||||
|
} else {
|
||||||
|
s12[sa12[i] / 3 + n0] = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name < n02) {
|
||||||
|
sa12 = skew(s12, n02, name);
|
||||||
|
for (int i = 0; i < n02; i++) {
|
||||||
|
s12[sa12[i]] = i + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < n02; i++) {
|
||||||
|
sa12[s12[i] - 1] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int[] s0 = new int[n0], sa0 = new int[n0];
|
||||||
|
for (int i = 0, j = 0; i < n02; i++) {
|
||||||
|
if (sa12[i] < n0) {
|
||||||
|
s0[j++] = 3 * sa12[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radixPass(nums, s0, sa0, 0, n0, K);
|
||||||
|
int[] sa = new int[n];
|
||||||
|
for (int p = 0, t = n0 - n1, k = 0; k < n; k++) {
|
||||||
|
int i = sa12[t] < n0 ? sa12[t] * 3 + 1 : (sa12[t] - n0) * 3 + 2;
|
||||||
|
int j = sa0[p];
|
||||||
|
if (sa12[t] < n0 ? leq(nums[i], s12[sa12[t] + n0], nums[j], s12[j / 3])
|
||||||
|
: leq(nums[i], nums[i + 1], s12[sa12[t] - n0 + 1], nums[j], nums[j + 1], s12[j / 3 + n0])) {
|
||||||
|
sa[k] = i;
|
||||||
|
t++;
|
||||||
|
if (t == n02) {
|
||||||
|
for (k++; p < n0; p++, k++) {
|
||||||
|
sa[k] = sa0[p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sa[k] = j;
|
||||||
|
p++;
|
||||||
|
if (p == n0) {
|
||||||
|
for (k++; t < n02; t++, k++) {
|
||||||
|
sa[k] = sa12[t] < n0 ? sa12[t] * 3 + 1 : (sa12[t] - n0) * 3 + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void radixPass(int[] nums, int[] input, int[] output, int offset, int n, int k) {
|
||||||
|
int[] cnt = new int[k + 1];
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
cnt[nums[input[i] + offset]]++;
|
||||||
|
}
|
||||||
|
for (int i = 0, sum = 0; i < cnt.length; ++i) {
|
||||||
|
int t = cnt[i];
|
||||||
|
cnt[i] = sum;
|
||||||
|
sum += t;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
output[cnt[nums[input[i] + offset]]++] = input[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean leq(int a1, int a2, int b1, int b2) {
|
||||||
|
return a1 < b1 || (a1 == b1 && a2 <= b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean leq(int a1, int a2, int a3, int b1, int b2, int b3) {
|
||||||
|
return a1 < b1 || (a1 == b1 && leq(a2, a3, b2, b3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] rank() {
|
||||||
|
int n = sa.length;
|
||||||
|
int[] ans = new int[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
ans[sa[i]] = i + 1;
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,249 @@
|
|||||||
|
package class44;
|
||||||
|
|
||||||
|
public class Code03_InsertS2MakeMostAlphabeticalOrder {
|
||||||
|
|
||||||
|
// 暴力方法
|
||||||
|
public static String right(String s1, String s2) {
|
||||||
|
if (s1 == null || s1.length() == 0) {
|
||||||
|
return s2;
|
||||||
|
}
|
||||||
|
if (s2 == null || s2.length() == 0) {
|
||||||
|
return s1;
|
||||||
|
}
|
||||||
|
String p1 = s1 + s2;
|
||||||
|
String p2 = s2 + s1;
|
||||||
|
String ans = p1.compareTo(p2) > 0 ? p1 : p2;
|
||||||
|
for (int end = 1; end < s1.length(); end++) {
|
||||||
|
String cur = s1.substring(0, end) + s2 + s1.substring(end);
|
||||||
|
if (cur.compareTo(ans) > 0) {
|
||||||
|
ans = cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 正式方法
|
||||||
|
public static String max(String s1, String s2) {
|
||||||
|
if (s1 == null || s1.length() == 0) {
|
||||||
|
return s2;
|
||||||
|
}
|
||||||
|
if (s2 == null || s2.length() == 0) {
|
||||||
|
return s1;
|
||||||
|
}
|
||||||
|
char[] str1 = s1.toCharArray();
|
||||||
|
char[] str2 = s2.toCharArray();
|
||||||
|
int N = str1.length;
|
||||||
|
int M = str2.length;
|
||||||
|
int min = str1[0];
|
||||||
|
int max = str1[0];
|
||||||
|
for (int i = 1; i < N; i++) {
|
||||||
|
min = Math.min(min, str1[i]);
|
||||||
|
max = Math.max(max, str1[i]);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < M; i++) {
|
||||||
|
min = Math.min(min, str2[i]);
|
||||||
|
max = Math.max(max, str2[i]);
|
||||||
|
}
|
||||||
|
int[] all = new int[N + M + 1];
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
all[index++] = str1[i] - min + 2;
|
||||||
|
}
|
||||||
|
all[index++] = 1;
|
||||||
|
for (int i = 0; i < M; i++) {
|
||||||
|
all[index++] = str2[i] - min + 2;
|
||||||
|
}
|
||||||
|
DC3 dc3 = new DC3(all, max - min + 2);
|
||||||
|
int[] rank = dc3.rank;
|
||||||
|
int comp = N + 1;
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
if (rank[i] < rank[comp]) {
|
||||||
|
int best = whereSplit(s1, s2, i);
|
||||||
|
return s1.substring(0, best) + s2 + s1.substring(best);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s1 + s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DC3 {
|
||||||
|
|
||||||
|
public int[] sa;
|
||||||
|
public int[] rank;
|
||||||
|
|
||||||
|
public DC3(int[] nums, int max) {
|
||||||
|
sa = sa(nums, max);
|
||||||
|
rank = rank();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] sa(int[] nums, int max) {
|
||||||
|
int n = nums.length;
|
||||||
|
int[] arr = new int[n + 3];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
arr[i] = nums[i];
|
||||||
|
}
|
||||||
|
return skew(arr, n, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] skew(int[] nums, int n, int K) {
|
||||||
|
int n0 = (n + 2) / 3, n1 = (n + 1) / 3, n2 = n / 3, n02 = n0 + n2;
|
||||||
|
int[] s12 = new int[n02 + 3], sa12 = new int[n02 + 3];
|
||||||
|
for (int i = 0, j = 0; i < n + (n0 - n1); ++i) {
|
||||||
|
if (0 != i % 3) {
|
||||||
|
s12[j++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radixPass(nums, s12, sa12, 2, n02, K);
|
||||||
|
radixPass(nums, sa12, s12, 1, n02, K);
|
||||||
|
radixPass(nums, s12, sa12, 0, n02, K);
|
||||||
|
int name = 0, c0 = -1, c1 = -1, c2 = -1;
|
||||||
|
for (int i = 0; i < n02; ++i) {
|
||||||
|
if (c0 != nums[sa12[i]] || c1 != nums[sa12[i] + 1] || c2 != nums[sa12[i] + 2]) {
|
||||||
|
name++;
|
||||||
|
c0 = nums[sa12[i]];
|
||||||
|
c1 = nums[sa12[i] + 1];
|
||||||
|
c2 = nums[sa12[i] + 2];
|
||||||
|
}
|
||||||
|
if (1 == sa12[i] % 3) {
|
||||||
|
s12[sa12[i] / 3] = name;
|
||||||
|
} else {
|
||||||
|
s12[sa12[i] / 3 + n0] = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name < n02) {
|
||||||
|
sa12 = skew(s12, n02, name);
|
||||||
|
for (int i = 0; i < n02; i++) {
|
||||||
|
s12[sa12[i]] = i + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < n02; i++) {
|
||||||
|
sa12[s12[i] - 1] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int[] s0 = new int[n0], sa0 = new int[n0];
|
||||||
|
for (int i = 0, j = 0; i < n02; i++) {
|
||||||
|
if (sa12[i] < n0) {
|
||||||
|
s0[j++] = 3 * sa12[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radixPass(nums, s0, sa0, 0, n0, K);
|
||||||
|
int[] sa = new int[n];
|
||||||
|
for (int p = 0, t = n0 - n1, k = 0; k < n; k++) {
|
||||||
|
int i = sa12[t] < n0 ? sa12[t] * 3 + 1 : (sa12[t] - n0) * 3 + 2;
|
||||||
|
int j = sa0[p];
|
||||||
|
if (sa12[t] < n0 ? leq(nums[i], s12[sa12[t] + n0], nums[j], s12[j / 3])
|
||||||
|
: leq(nums[i], nums[i + 1], s12[sa12[t] - n0 + 1], nums[j], nums[j + 1], s12[j / 3 + n0])) {
|
||||||
|
sa[k] = i;
|
||||||
|
t++;
|
||||||
|
if (t == n02) {
|
||||||
|
for (k++; p < n0; p++, k++) {
|
||||||
|
sa[k] = sa0[p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sa[k] = j;
|
||||||
|
p++;
|
||||||
|
if (p == n0) {
|
||||||
|
for (k++; t < n02; t++, k++) {
|
||||||
|
sa[k] = sa12[t] < n0 ? sa12[t] * 3 + 1 : (sa12[t] - n0) * 3 + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void radixPass(int[] nums, int[] input, int[] output, int offset, int n, int k) {
|
||||||
|
int[] cnt = new int[k + 1];
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
cnt[nums[input[i] + offset]]++;
|
||||||
|
}
|
||||||
|
for (int i = 0, sum = 0; i < cnt.length; ++i) {
|
||||||
|
int t = cnt[i];
|
||||||
|
cnt[i] = sum;
|
||||||
|
sum += t;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
output[cnt[nums[input[i] + offset]]++] = input[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean leq(int a1, int a2, int b1, int b2) {
|
||||||
|
return a1 < b1 || (a1 == b1 && a2 <= b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean leq(int a1, int a2, int a3, int b1, int b2, int b3) {
|
||||||
|
return a1 < b1 || (a1 == b1 && leq(a2, a3, b2, b3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] rank() {
|
||||||
|
int n = sa.length;
|
||||||
|
int[] ans = new int[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
ans[sa[i]] = i + 1;
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int whereSplit(String str1, String str2, int first) {
|
||||||
|
int M = str2.length();
|
||||||
|
String bestPrefix = str2;
|
||||||
|
int bestSplit = first;
|
||||||
|
for (int i = first + 1, j = M - 1; i <= Math.min(str1.length(), first + M); i++, j--) {
|
||||||
|
String curPrefix = str1.substring(first, i) + str2.substring(0, j);
|
||||||
|
if (curPrefix.compareTo(bestPrefix) >= 0) {
|
||||||
|
bestPrefix = curPrefix;
|
||||||
|
bestSplit = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestSplit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static String randomNumberString(int len, int range) {
|
||||||
|
char[] str = new char[len];
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
str[i] = (char) ((int) (Math.random() * range) + '0');
|
||||||
|
}
|
||||||
|
return String.valueOf(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int range = 10;
|
||||||
|
int len = 50;
|
||||||
|
int testTime = 100000;
|
||||||
|
System.out.println("功能测试开始");
|
||||||
|
for (int i = 0; i < testTime; i++) {
|
||||||
|
int s1Len = (int) (Math.random() * len);
|
||||||
|
int s2Len = (int) (Math.random() * len);
|
||||||
|
String s1 = randomNumberString(s1Len, range);
|
||||||
|
String s2 = randomNumberString(s2Len, range);
|
||||||
|
String ans1 = right(s1, s2);
|
||||||
|
String ans2 = max(s1, s2);
|
||||||
|
if (!ans1.equals(ans2)) {
|
||||||
|
System.out.println("Oops!");
|
||||||
|
System.out.println(s1);
|
||||||
|
System.out.println(s2);
|
||||||
|
System.out.println(ans1);
|
||||||
|
System.out.println(ans2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("功能测试结束");
|
||||||
|
System.out.println("==========");
|
||||||
|
System.out.println("性能测试开始");
|
||||||
|
|
||||||
|
int s1Len = 1000000;
|
||||||
|
int s2Len = 50;
|
||||||
|
String s1 = randomNumberString(s1Len, range);
|
||||||
|
String s2 = randomNumberString(s2Len, range);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
max(s1, s2);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
System.out.println("运行时间 : " + (end - start) + " ms");
|
||||||
|
System.out.println("性能测试结束");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
package class44;
|
||||||
|
|
||||||
|
public class DC3 {
|
||||||
|
|
||||||
|
public int[] sa;
|
||||||
|
|
||||||
|
public int[] rank;
|
||||||
|
|
||||||
|
public DC3(int[] nums, int max) {
|
||||||
|
sa = sa(nums, max);
|
||||||
|
rank = rank();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] sa(int[] nums, int max) {
|
||||||
|
int n = nums.length;
|
||||||
|
int[] arr = new int[n + 3];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
arr[i] = nums[i];
|
||||||
|
}
|
||||||
|
return skew(arr, n, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] skew(int[] nums, int n, int K) {
|
||||||
|
int n0 = (n + 2) / 3, n1 = (n + 1) / 3, n2 = n / 3, n02 = n0 + n2;
|
||||||
|
int[] s12 = new int[n02 + 3], sa12 = new int[n02 + 3];
|
||||||
|
for (int i = 0, j = 0; i < n + (n0 - n1); ++i) {
|
||||||
|
if (0 != i % 3) {
|
||||||
|
s12[j++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radixPass(nums, s12, sa12, 2, n02, K);
|
||||||
|
radixPass(nums, sa12, s12, 1, n02, K);
|
||||||
|
radixPass(nums, s12, sa12, 0, n02, K);
|
||||||
|
int name = 0, c0 = -1, c1 = -1, c2 = -1;
|
||||||
|
for (int i = 0; i < n02; ++i) {
|
||||||
|
if (c0 != nums[sa12[i]] || c1 != nums[sa12[i] + 1] || c2 != nums[sa12[i] + 2]) {
|
||||||
|
name++;
|
||||||
|
c0 = nums[sa12[i]];
|
||||||
|
c1 = nums[sa12[i] + 1];
|
||||||
|
c2 = nums[sa12[i] + 2];
|
||||||
|
}
|
||||||
|
if (1 == sa12[i] % 3) {
|
||||||
|
s12[sa12[i] / 3] = name;
|
||||||
|
} else {
|
||||||
|
s12[sa12[i] / 3 + n0] = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name < n02) {
|
||||||
|
sa12 = skew(s12, n02, name);
|
||||||
|
for (int i = 0; i < n02; i++) {
|
||||||
|
s12[sa12[i]] = i + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < n02; i++) {
|
||||||
|
sa12[s12[i] - 1] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int[] s0 = new int[n0], sa0 = new int[n0];
|
||||||
|
for (int i = 0, j = 0; i < n02; i++) {
|
||||||
|
if (sa12[i] < n0) {
|
||||||
|
s0[j++] = 3 * sa12[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radixPass(nums, s0, sa0, 0, n0, K);
|
||||||
|
int[] sa = new int[n];
|
||||||
|
for (int p = 0, t = n0 - n1, k = 0; k < n; k++) {
|
||||||
|
int i = sa12[t] < n0 ? sa12[t] * 3 + 1 : (sa12[t] - n0) * 3 + 2;
|
||||||
|
int j = sa0[p];
|
||||||
|
if (sa12[t] < n0 ? leq(nums[i], s12[sa12[t] + n0], nums[j], s12[j / 3])
|
||||||
|
: leq(nums[i], nums[i + 1], s12[sa12[t] - n0 + 1], nums[j], nums[j + 1], s12[j / 3 + n0])) {
|
||||||
|
sa[k] = i;
|
||||||
|
t++;
|
||||||
|
if (t == n02) {
|
||||||
|
for (k++; p < n0; p++, k++) {
|
||||||
|
sa[k] = sa0[p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sa[k] = j;
|
||||||
|
p++;
|
||||||
|
if (p == n0) {
|
||||||
|
for (k++; t < n02; t++, k++) {
|
||||||
|
sa[k] = sa12[t] < n0 ? sa12[t] * 3 + 1 : (sa12[t] - n0) * 3 + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void radixPass(int[] nums, int[] input, int[] output, int offset, int n, int k) {
|
||||||
|
int[] cnt = new int[k + 1];
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
cnt[nums[input[i] + offset]]++;
|
||||||
|
}
|
||||||
|
for (int i = 0, sum = 0; i < cnt.length; ++i) {
|
||||||
|
int t = cnt[i];
|
||||||
|
cnt[i] = sum;
|
||||||
|
sum += t;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
output[cnt[nums[input[i] + offset]]++] = input[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean leq(int a1, int a2, int b1, int b2) {
|
||||||
|
return a1 < b1 || (a1 == b1 && a2 <= b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean leq(int a1, int a2, int a3, int b1, int b2, int b3) {
|
||||||
|
return a1 < b1 || (a1 == b1 && leq(a2, a3, b2, b3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] rank() {
|
||||||
|
int n = sa.length;
|
||||||
|
int[] ans = new int[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
ans[sa[i]] = i + 1;
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
@ -0,0 +1,33 @@
|
|||||||
|
package class45;
|
||||||
|
|
||||||
|
public class Code03_StrangePrinter {
|
||||||
|
|
||||||
|
public static int strangePrinter(String s) {
|
||||||
|
if (s == null || s.length() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
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] ? 1 : 2;
|
||||||
|
}
|
||||||
|
for (int L = N - 3; L >= 0; L--) {
|
||||||
|
for (int R = L + 2; R < N; R++) {
|
||||||
|
|
||||||
|
// L....R
|
||||||
|
|
||||||
|
dp[L][R] = R - L + 1;
|
||||||
|
|
||||||
|
// L...k-1 k...R
|
||||||
|
for (int k = L + 1; k <= R; k++) {
|
||||||
|
dp[L][R] = Math.min(dp[L][R], dp[L][k - 1] + dp[k][R] - (str[L] == str[k] ? 1 : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[0][N - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue