parent
a19d982cf7
commit
64d7b5cd1f
@ -0,0 +1,35 @@
|
||||
package 第01期_mca_01_about_sort;
|
||||
|
||||
// leetcode 875题
|
||||
public class Code05_KokoEatingBananas {
|
||||
|
||||
public static int minEatingSpeed(int[] piles, int h) {
|
||||
int L = 1;
|
||||
int R = 0;
|
||||
for (int pile : piles) {
|
||||
R = Math.max(R, pile);
|
||||
}
|
||||
int ans = 0;
|
||||
int M = 0;
|
||||
while (L <= R) {
|
||||
M = L + ((R - L) >> 1);
|
||||
if (hours(piles, M) <= h) {
|
||||
ans = M;
|
||||
R = M - 1;
|
||||
} else {
|
||||
L = M + 1;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static int hours(int[] piles, int speed) {
|
||||
int ans = 0;
|
||||
int offset = speed - 1;
|
||||
for (int pile : piles) {
|
||||
ans += (pile + offset) / speed;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package 第01期_mca_02_about_coding;
|
||||
|
||||
public class Code03_PrintMatrixZigZag {
|
||||
|
||||
public static void print(int[][] matrix) {
|
||||
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
|
||||
return;
|
||||
}
|
||||
int leftUpRow = 0;
|
||||
int leftUpCol = 0;
|
||||
int rightDownRow = matrix.length - 1;
|
||||
int rightDownCol = matrix[0].length - 1;
|
||||
// 还没结束!
|
||||
while (leftUpRow <= rightDownRow && leftUpCol <= rightDownCol) {
|
||||
f(matrix, leftUpRow++, leftUpCol++, rightDownRow--, rightDownCol--);
|
||||
}
|
||||
}
|
||||
|
||||
// 打印框!
|
||||
public static void f(int[][] matrix, int leftUpRow, int leftUpCol, int rightDownRow, int rightDownCol) {
|
||||
if (leftUpRow == rightDownRow && leftUpCol == rightDownCol) {
|
||||
System.out.print(matrix[leftUpRow][leftUpCol] + " ");
|
||||
} else { // 不是一个数!
|
||||
if (leftUpRow == rightDownRow) { // 当前的框是一条横线
|
||||
for (int col = leftUpCol; col <= rightDownCol; col++) {
|
||||
System.out.print(matrix[leftUpRow][col] + " ");
|
||||
}
|
||||
} else if (leftUpCol == rightDownCol) { // 当前的框是一条竖线
|
||||
for (int row = leftUpRow; row <= rightDownRow; row++) {
|
||||
System.out.print(matrix[row][leftUpCol] + " ");
|
||||
}
|
||||
} else { // 正常的框
|
||||
for (int col = leftUpCol; col < rightDownCol; col++) {
|
||||
System.out.print(matrix[leftUpRow][col] + " ");
|
||||
}
|
||||
for (int row = leftUpRow; row < rightDownRow; row++) {
|
||||
System.out.print(matrix[row][rightDownCol] + " ");
|
||||
}
|
||||
for (int col = rightDownCol; col > leftUpCol; col--) {
|
||||
System.out.print(matrix[rightDownRow][col] + " ");
|
||||
}
|
||||
for (int row = rightDownRow; row > leftUpRow; row--) {
|
||||
System.out.print(matrix[row][leftUpCol] + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[][] matrix = {
|
||||
{ 1, 2, 3},
|
||||
{ 4, 5, 6},
|
||||
{ 7, 8 ,9}
|
||||
};
|
||||
print(matrix);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package 第01期_mca_02_about_coding;
|
||||
|
||||
public class Code04_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 Arow, int ACol, int Brow, int Bcol, boolean f) {
|
||||
if (f) {
|
||||
while (Arow != Brow + 1) {
|
||||
System.out.print(m[Arow++][ACol--] + " ");
|
||||
}
|
||||
} else {
|
||||
while (Brow != Arow - 1) {
|
||||
System.out.print(m[Brow--][Bcol++] + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,49 @@
|
||||
package 第01期_mca_03_about_experience;
|
||||
|
||||
// 测试链接 : https://leetcode.com/problems/best-meeting-point/
|
||||
public class Code03_BestMeetingPoint {
|
||||
|
||||
public static int minTotalDistance(int[][] grid) {
|
||||
int N = grid.length;
|
||||
int M = grid[0].length;
|
||||
int[] iOnes = new int[N];
|
||||
int[] jOnes = new int[M];
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (int j = 0; j < M; j++) {
|
||||
if (grid[i][j] == 1) {
|
||||
iOnes[i]++;
|
||||
jOnes[j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
int total = 0;
|
||||
int i = 0;
|
||||
int j = N - 1;
|
||||
int iRest = 0;
|
||||
int jRest = 0;
|
||||
while (i < j) {
|
||||
if (iOnes[i] + iRest <= iOnes[j] + jRest) {
|
||||
total += iOnes[i] + iRest;
|
||||
iRest += iOnes[i++];
|
||||
} else {
|
||||
total += iOnes[j] + jRest;
|
||||
jRest += iOnes[j--];
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
j = M - 1;
|
||||
iRest = 0;
|
||||
jRest = 0;
|
||||
while (i < j) {
|
||||
if (jOnes[i] + iRest <= jOnes[j] + jRest) {
|
||||
total += jOnes[i] + iRest;
|
||||
iRest += jOnes[i++];
|
||||
} else {
|
||||
total += jOnes[j] + jRest;
|
||||
jRest += jOnes[j--];
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package 第01期_mca_03_about_experience;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Code06_SetAll {
|
||||
|
||||
public static class MyValue<V> {
|
||||
public V value;
|
||||
public long time;
|
||||
|
||||
public MyValue(V v, long t) {
|
||||
value = v;
|
||||
time = t;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyHashMap<K, V> {
|
||||
private HashMap<K, MyValue<V>> map;
|
||||
private long time;
|
||||
private MyValue<V> setAll;
|
||||
|
||||
public MyHashMap() {
|
||||
map = new HashMap<>();
|
||||
time = 0;
|
||||
setAll = new MyValue<V>(null, -1);
|
||||
}
|
||||
|
||||
public void put(K key, V value) {
|
||||
map.put(key, new MyValue<V>(value, time++));
|
||||
}
|
||||
|
||||
public void setAll(V value) {
|
||||
setAll = new MyValue<V>(value, time++);
|
||||
}
|
||||
|
||||
public V get(K key) {
|
||||
if (!map.containsKey(key)) {
|
||||
return null;
|
||||
}
|
||||
if (map.get(key).time > setAll.time) {
|
||||
return map.get(key).value;
|
||||
} else {
|
||||
return setAll.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package 第01期_mca_04_about_data_structure;
|
||||
|
||||
public class Code02_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,67 @@
|
||||
package 第01期_mca_04_about_data_structure;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class Code06_AllTimesMinToMax {
|
||||
|
||||
public static int max1(int[] arr) {
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
for (int j = i; j < arr.length; j++) {
|
||||
int minNum = Integer.MAX_VALUE;
|
||||
int sum = 0;
|
||||
for (int k = i; k <= j; k++) {
|
||||
sum += arr[k];
|
||||
minNum = Math.min(minNum, arr[k]);
|
||||
}
|
||||
max = Math.max(max, minNum * sum);
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static int max2(int[] arr) {
|
||||
int size = arr.length;
|
||||
int[] sums = new int[size];
|
||||
sums[0] = arr[0];
|
||||
for (int i = 1; i < size; i++) {
|
||||
sums[i] = sums[i - 1] + arr[i];
|
||||
}
|
||||
int max = Integer.MIN_VALUE;
|
||||
Stack<Integer> stack = new Stack<Integer>();
|
||||
for (int i = 0; i < size; i++) {
|
||||
while (!stack.isEmpty() && arr[stack.peek()] >= arr[i]) {
|
||||
int j = stack.pop();
|
||||
max = Math.max(max, (stack.isEmpty() ? sums[i - 1] : (sums[i - 1] - sums[stack.peek()])) * arr[j]);
|
||||
}
|
||||
stack.push(i);
|
||||
}
|
||||
while (!stack.isEmpty()) {
|
||||
int j = stack.pop();
|
||||
max = Math.max(max, (stack.isEmpty() ? sums[size - 1] : (sums[size - 1] - sums[stack.peek()])) * arr[j]);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static int[] gerenareRondomArray() {
|
||||
int[] arr = new int[(int) (Math.random() * 20) + 10];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = (int) (Math.random() * 101);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int testTimes = 2000000;
|
||||
System.out.println("test begin");
|
||||
for (int i = 0; i < testTimes; i++) {
|
||||
int[] arr = gerenareRondomArray();
|
||||
if (max1(arr) != max2(arr)) {
|
||||
System.out.println("FUCK!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("test finish");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package 第01期_mca_05_about_math_greedy;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
// leetcode 630题
|
||||
public class Code05_CourseScheduleIII {
|
||||
|
||||
public static int scheduleCourse(int[][] courses) {
|
||||
// courses[i] = {花费,截止}
|
||||
Arrays.sort(courses, (a, b) -> a[1] - b[1]);
|
||||
// 花费时间的大根堆
|
||||
PriorityQueue<Integer> heap = new PriorityQueue<>((a, b) -> b - a);
|
||||
// 时间点
|
||||
int time = 0;
|
||||
for (int[] c : courses) {
|
||||
//
|
||||
if (time + c[0] <= c[1]) { // 当前时间 + 花费 <= 截止时间的
|
||||
heap.add(c[0]);
|
||||
time += c[0];
|
||||
} else { // 当前时间 + 花费 > 截止时间的, 只有淘汰掉某课,当前的课才能进来!
|
||||
//
|
||||
if (!heap.isEmpty() && heap.peek() > c[0]) {
|
||||
// time -= heap.poll();
|
||||
// heap.add(c[0]);
|
||||
// time += c[0];
|
||||
heap.add(c[0]);
|
||||
time += c[0] - heap.poll();
|
||||
}
|
||||
}
|
||||
}
|
||||
return heap.size();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package 第01期_mca_07_about_monotonicity;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Code01_CordCoverMaxPoint {
|
||||
|
||||
public static int maxPoint1(int[] arr, int L) {
|
||||
int res = 1;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
int nearest = nearestIndex(arr, i, arr[i] - L);
|
||||
res = Math.max(res, i - nearest + 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static int nearestIndex(int[] arr, int R, int value) {
|
||||
int L = 0;
|
||||
int index = R;
|
||||
while (L <= R) {
|
||||
int mid = L + ((R - L) >> 1);
|
||||
if (arr[mid] >= value) {
|
||||
index = mid;
|
||||
R = mid - 1;
|
||||
} else {
|
||||
L = mid + 1;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public static int maxPoint2(int[] arr, int L) {
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int N = arr.length;
|
||||
int max = 0;
|
||||
while (left < N) {
|
||||
while (right < N && arr[right] - arr[left] <= L) {
|
||||
right++;
|
||||
}
|
||||
max = Math.max(max, right - (left++));
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int test(int[] arr, int L) {
|
||||
int max = 0;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
int pre = i - 1;
|
||||
while (pre >= 0 && arr[i] - arr[pre] <= L) {
|
||||
pre--;
|
||||
}
|
||||
max = Math.max(max, i - pre);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] generateArray(int len, int max) {
|
||||
int[] ans = new int[(int) (Math.random() * len) + 1];
|
||||
for (int i = 0; i < ans.length; i++) {
|
||||
ans[i] = (int) (Math.random() * max);
|
||||
}
|
||||
Arrays.sort(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int len = 100;
|
||||
int max = 1000;
|
||||
int testTime = 100000;
|
||||
System.out.println("测试开始");
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int L = (int) (Math.random() * max);
|
||||
int[] arr = generateArray(len, max);
|
||||
int ans1 = maxPoint1(arr, L);
|
||||
int ans2 = maxPoint2(arr, L);
|
||||
int ans3 = test(arr, L);
|
||||
if (ans1 != ans2 || ans2 != ans3) {
|
||||
System.out.println("oops!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package 第01期_mca_07_about_monotonicity;
|
||||
|
||||
public class Code02_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,28 @@
|
||||
package 第01期_mca_07_about_monotonicity;
|
||||
|
||||
// 本题测试链接 : https://leetcode.com/problems/trapping-rain-water/
|
||||
public class Code04_TrappingRainWater {
|
||||
|
||||
public static int trap(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
int L = 1;
|
||||
int leftMax = arr[0];
|
||||
int R = N - 2;
|
||||
int rightMax = arr[N - 1];
|
||||
int water = 0;
|
||||
while (L <= R) {
|
||||
if (leftMax <= rightMax) {
|
||||
water += Math.max(0, leftMax - arr[L]);
|
||||
leftMax = Math.max(leftMax, arr[L++]);
|
||||
} else {
|
||||
water += Math.max(0, rightMax - arr[R]);
|
||||
rightMax = Math.max(rightMax, arr[R--]);
|
||||
}
|
||||
}
|
||||
return water;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package 第01期_mca_07_about_monotonicity;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Code06_IsStepSum {
|
||||
|
||||
public static boolean isStepSum(int stepSum) {
|
||||
int L = 0;
|
||||
int R = stepSum;
|
||||
int M = 0;
|
||||
int cur = 0;
|
||||
while (L <= R) {
|
||||
M = L + ((R - L) >> 1);
|
||||
cur = stepSum(M);
|
||||
if (cur == stepSum) {
|
||||
return true;
|
||||
} else if (cur < stepSum) {
|
||||
L = M + 1;
|
||||
} else {
|
||||
R = M - 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int stepSum(int num) {
|
||||
int sum = 0;
|
||||
while (num != 0) {
|
||||
sum += num;
|
||||
num /= 10;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static HashMap<Integer, Integer> generateStepSumNumberMap(int numMax) {
|
||||
HashMap<Integer, Integer> map = new HashMap<>();
|
||||
for (int i = 0; i <= numMax; i++) {
|
||||
map.put(stepSum(i), i);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void main(String[] args) {
|
||||
int max = 1000000;
|
||||
int maxStepSum = stepSum(max);
|
||||
HashMap<Integer, Integer> ans = generateStepSumNumberMap(max);
|
||||
System.out.println("测试开始");
|
||||
for (int i = 0; i <= maxStepSum; i++) {
|
||||
if (isStepSum(i) ^ ans.containsKey(i)) {
|
||||
System.out.println("出错了!");
|
||||
}
|
||||
}
|
||||
System.out.println("测试结束");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package 第01期_mca_07_about_monotonicity;
|
||||
|
||||
public class Code07_MinWindowLength {
|
||||
|
||||
// 字符串都是小写字母
|
||||
public static int validMinLen(String s1, String s2) {
|
||||
char[] str1 = s1.toCharArray();
|
||||
char[] str2 = s2.toCharArray();
|
||||
int n = str1.length;
|
||||
int m = str2.length;
|
||||
if (n < m) {
|
||||
return -1;
|
||||
}
|
||||
// n >= m
|
||||
int[] counts = new int[256];
|
||||
for (char s2char : str2) {
|
||||
counts[s2char]++;
|
||||
}
|
||||
int all = m;
|
||||
int ans = Integer.MAX_VALUE;
|
||||
int r = 0;
|
||||
// [i..r)
|
||||
for (int i = 0; i < n; i++) {
|
||||
r = Math.max(r, i);
|
||||
while (r < n && all > 0) {
|
||||
counts[str1[r]]--;
|
||||
if (counts[str1[r]] >= 0) {
|
||||
all--;
|
||||
}
|
||||
r++;
|
||||
}
|
||||
if (all == 0) {
|
||||
ans = Math.min(ans, r - i);
|
||||
}
|
||||
counts[str1[i]]++;
|
||||
if (counts[str1[i]] > 0) {
|
||||
all++;
|
||||
}
|
||||
}
|
||||
return ans == Integer.MAX_VALUE ? -1 : ans;
|
||||
}
|
||||
|
||||
public static int minLength(String s1, String s2) {
|
||||
if (s1 == null || s2 == null || s1.length() < s2.length()) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
char[] str1 = s1.toCharArray();
|
||||
char[] str2 = s2.toCharArray();
|
||||
int[] map = new int[256]; // map[37] = 4 37 4次
|
||||
for (int i = 0; i != str2.length; i++) {
|
||||
map[str2[i]]++;
|
||||
}
|
||||
int all = str2.length;
|
||||
int L = 0;
|
||||
int R = 0;
|
||||
int minLen = Integer.MAX_VALUE;
|
||||
while (R != str1.length) {
|
||||
map[str1[R]]--;
|
||||
if (map[str1[R]] >= 0) {
|
||||
all--;
|
||||
}
|
||||
if (all == 0) {
|
||||
while (map[str1[L]] < 0) {
|
||||
map[str1[L++]]++;
|
||||
}
|
||||
minLen = Math.min(minLen, R - L + 1);
|
||||
all++;
|
||||
map[str1[L++]]++;
|
||||
}
|
||||
R++;
|
||||
}
|
||||
return minLen == Integer.MAX_VALUE ? 0 : minLen;
|
||||
}
|
||||
|
||||
// 测试链接 : https://leetcode.com/problems/minimum-window-substring/
|
||||
public static String minWindow(String s, String t) {
|
||||
if (s.length() < t.length()) {
|
||||
return "";
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
char[] target = t.toCharArray();
|
||||
int[] map = new int[256];
|
||||
for (char cha : target) {
|
||||
map[cha]++;
|
||||
}
|
||||
int all = target.length;
|
||||
int L = 0;
|
||||
int R = 0;
|
||||
int minLen = Integer.MAX_VALUE;
|
||||
int ansl = -1;
|
||||
int ansr = -1;
|
||||
while (R != str.length) {
|
||||
map[str[R]]--;
|
||||
if (map[str[R]] >= 0) {
|
||||
all--;
|
||||
}
|
||||
if (all == 0) {
|
||||
while (map[str[L]] < 0) {
|
||||
map[str[L++]]++;
|
||||
}
|
||||
if (minLen > R - L + 1) {
|
||||
minLen = R - L + 1;
|
||||
ansl = L;
|
||||
ansr = R;
|
||||
}
|
||||
all++;
|
||||
map[str[L++]]++;
|
||||
}
|
||||
R++;
|
||||
}
|
||||
return minLen == Integer.MAX_VALUE ? "" : s.substring(ansl, ansr + 1);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package 第01期_mca_08_dp;
|
||||
|
||||
// 本题测试链接 : https://leetcode.com/problems/longest-substring-without-repeating-characters/
|
||||
public class Code03_LongestSubstringWithoutRepeatingCharacters {
|
||||
|
||||
public static int lengthOfLongestSubstring(String s) {
|
||||
if (s == null || s.equals("")) {
|
||||
return 0;
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
int[] map = new int[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
map[i] = -1;
|
||||
}
|
||||
map[str[0]] = 0;
|
||||
int N = str.length;
|
||||
int ans = 1;
|
||||
int pre = 1;
|
||||
for (int i = 1; i < N; i++) {
|
||||
pre = Math.min(i - map[str[i]], pre + 1);
|
||||
ans = Math.max(ans, pre);
|
||||
map[str[i]] = i;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package 第01期_mca_08_dp;
|
||||
|
||||
public class Code08_EditCost {
|
||||
|
||||
public static int minCost1(String s1, String s2, int ic, int dc, int rc) {
|
||||
if (s1 == null || s2 == null) {
|
||||
return 0;
|
||||
}
|
||||
char[] str1 = s1.toCharArray();
|
||||
char[] str2 = s2.toCharArray();
|
||||
int N = str1.length + 1;
|
||||
int M = str2.length + 1;
|
||||
int[][] dp = new int[N][M];
|
||||
// dp[0][0] = 0
|
||||
for (int i = 1; i < N; i++) {
|
||||
dp[i][0] = dc * i;
|
||||
}
|
||||
for (int j = 1; j < M; j++) {
|
||||
dp[0][j] = ic * j;
|
||||
}
|
||||
for (int i = 1; i < N; i++) {
|
||||
for (int j = 1; j < M; j++) {
|
||||
dp[i][j] = dp[i - 1][j - 1] + (str1[i - 1] == str2[j - 1] ? 0 : rc);
|
||||
dp[i][j] = Math.min(dp[i][j], dp[i][j - 1] + ic);
|
||||
dp[i][j] = Math.min(dp[i][j], dp[i - 1][j] + dc);
|
||||
}
|
||||
}
|
||||
return dp[N - 1][M - 1];
|
||||
}
|
||||
|
||||
public static int minCost2(String str1, String str2, int ic, int dc, int rc) {
|
||||
if (str1 == null || str2 == null) {
|
||||
return 0;
|
||||
}
|
||||
char[] chs1 = str1.toCharArray();
|
||||
char[] chs2 = str2.toCharArray();
|
||||
char[] longs = chs1.length >= chs2.length ? chs1 : chs2;
|
||||
char[] shorts = chs1.length < chs2.length ? chs1 : chs2;
|
||||
if (chs1.length < chs2.length) {
|
||||
int tmp = ic;
|
||||
ic = dc;
|
||||
dc = tmp;
|
||||
}
|
||||
int[] dp = new int[shorts.length + 1];
|
||||
for (int i = 1; i <= shorts.length; i++) {
|
||||
dp[i] = ic * i;
|
||||
}
|
||||
for (int i = 1; i <= longs.length; i++) {
|
||||
int pre = dp[0];
|
||||
dp[0] = dc * i;
|
||||
for (int j = 1; j <= shorts.length; j++) {
|
||||
int tmp = dp[j];
|
||||
if (longs[i - 1] == shorts[j - 1]) {
|
||||
dp[j] = pre;
|
||||
} else {
|
||||
dp[j] = pre + rc;
|
||||
}
|
||||
dp[j] = Math.min(dp[j], dp[j - 1] + ic);
|
||||
dp[j] = Math.min(dp[j], tmp + dc);
|
||||
pre = tmp;
|
||||
}
|
||||
}
|
||||
return dp[shorts.length];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String str1 = "ab12cd3";
|
||||
String str2 = "abcdf";
|
||||
System.out.println(minCost1(str1, str2, 5, 3, 2));
|
||||
System.out.println(minCost2(str1, str2, 5, 3, 2));
|
||||
|
||||
str1 = "abcdf";
|
||||
str2 = "ab12cd3";
|
||||
System.out.println(minCost1(str1, str2, 3, 2, 4));
|
||||
System.out.println(minCost2(str1, str2, 3, 2, 4));
|
||||
|
||||
str1 = "";
|
||||
str2 = "ab12cd3";
|
||||
System.out.println(minCost1(str1, str2, 1, 7, 5));
|
||||
System.out.println(minCost2(str1, str2, 1, 7, 5));
|
||||
|
||||
str1 = "abcdf";
|
||||
str2 = "";
|
||||
System.out.println(minCost1(str1, str2, 2, 9, 8));
|
||||
System.out.println(minCost2(str1, str2, 2, 9, 8));
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package 第01期_test;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class Code02_AllLessNumSubArray {
|
||||
|
||||
// 暴力的对数器方法
|
||||
public static int right(int[] arr, int sum) {
|
||||
if (arr == null || arr.length == 0 || sum < 0) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
int count = 0;
|
||||
for (int L = 0; L < N; L++) {
|
||||
for (int R = L; R < N; R++) {
|
||||
int max = arr[L];
|
||||
int min = arr[L];
|
||||
for (int i = L + 1; i <= R; i++) {
|
||||
max = Math.max(max, arr[i]);
|
||||
min = Math.min(min, arr[i]);
|
||||
}
|
||||
if (max - min <= sum) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static int num(int[] arr, int sum) {
|
||||
if (arr == null || arr.length == 0 || sum < 0) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
int count = 0;
|
||||
LinkedList<Integer> maxWindow = new LinkedList<>();
|
||||
LinkedList<Integer> minWindow = new LinkedList<>();
|
||||
int R = 0;
|
||||
for (int L = 0; L < N; L++) {
|
||||
while (R < N) {
|
||||
while (!maxWindow.isEmpty() && arr[maxWindow.peekLast()] <= arr[R]) {
|
||||
maxWindow.pollLast();
|
||||
}
|
||||
maxWindow.addLast(R);
|
||||
while (!minWindow.isEmpty() && arr[minWindow.peekLast()] >= arr[R]) {
|
||||
minWindow.pollLast();
|
||||
}
|
||||
minWindow.addLast(R);
|
||||
if (arr[maxWindow.peekFirst()] - arr[minWindow.peekFirst()] > sum) {
|
||||
break;
|
||||
} else {
|
||||
R++;
|
||||
}
|
||||
}
|
||||
count += R - L;
|
||||
if (maxWindow.peekFirst() == L) {
|
||||
maxWindow.pollFirst();
|
||||
}
|
||||
if (minWindow.peekFirst() == L) {
|
||||
minWindow.pollFirst();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static int[] generateRandomArray(int maxLen, int maxValue) {
|
||||
int len = (int) (Math.random() * (maxLen + 1));
|
||||
int[] arr = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
arr[i] = (int) (Math.random() * (maxValue + 1)) - (int) (Math.random() * (maxValue + 1));
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// for test
|
||||
public static void printArray(int[] arr) {
|
||||
if (arr != null) {
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
System.out.print(arr[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int maxLen = 100;
|
||||
int maxValue = 200;
|
||||
int testTime = 100000;
|
||||
System.out.println("测试开始");
|
||||
for (int i = 0; i < testTime; i++) {
|
||||
int[] arr = generateRandomArray(maxLen, maxValue);
|
||||
int sum = (int) (Math.random() * (maxValue + 1));
|
||||
int ans1 = right(arr, sum);
|
||||
int ans2 = num(arr, sum);
|
||||
if (ans1 != ans2) {
|
||||
System.out.println("Oops!");
|
||||
printArray(arr);
|
||||
System.out.println(sum);
|
||||
System.out.println(ans1);
|
||||
System.out.println(ans2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("测试结束");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package 第01期_test;
|
||||
|
||||
//leetcode 122
|
||||
public class Code02_BestTimeToBuyAndSellStockII {
|
||||
|
||||
public static int maxProfit(int[] prices) {
|
||||
if (prices == null || prices.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int ans = 0;
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
ans += Math.max(prices[i] - prices[i-1], 0);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package 第01期_test;
|
||||
|
||||
// 本题测试链接 : https://leetcode.com/problems/container-with-most-water/
|
||||
public class Code02_ContainerWithMostWater {
|
||||
|
||||
public static int maxArea1(int[] h) {
|
||||
int max = 0;
|
||||
int N = h.length;
|
||||
for (int i = 0; i < N; i++) { // h[i]
|
||||
for (int j = i + 1; j < N; j++) { // h[j]
|
||||
max = Math.max(max, Math.min(h[i], h[j]) * (j - i));
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static int maxArea2(int[] h) {
|
||||
int max = 0;
|
||||
int l = 0;
|
||||
int r = h.length - 1;
|
||||
while (l < r) {
|
||||
max = Math.max(max, Math.min(h[l], h[r]) * (r - l));
|
||||
if (h[l] > h[r]) {
|
||||
r--;
|
||||
} else {
|
||||
l++;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package 第01期_test;
|
||||
|
||||
//leetcode 123
|
||||
public class Code03_BestTimeToBuyAndSellStockIII {
|
||||
|
||||
public static int maxProfit(int[] prices) {
|
||||
if (prices == null || prices.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
int ans = 0;
|
||||
int doneOnceMinusBuyMax = -prices[0];
|
||||
int doneOnceMax = 0;
|
||||
int min = prices[0];
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
min = Math.min(min, prices[i]);
|
||||
ans = Math.max(ans, doneOnceMinusBuyMax + prices[i]);
|
||||
doneOnceMax = Math.max(doneOnceMax, prices[i] - min);
|
||||
doneOnceMinusBuyMax = Math.max(doneOnceMinusBuyMax, doneOnceMax - prices[i]);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package 第01期_test;
|
||||
|
||||
public class Code03_SplitNumber {
|
||||
|
||||
// n为正数
|
||||
public static int ways(int n) {
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (n == 1) {
|
||||
return 1;
|
||||
}
|
||||
return process(1, n);
|
||||
}
|
||||
|
||||
// 上一个拆出来的数是pre
|
||||
// 还剩rest需要去拆
|
||||
// 返回拆解的方法数
|
||||
public static int process(int pre, int rest) {
|
||||
if (rest == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (pre > rest) {
|
||||
return 0;
|
||||
}
|
||||
int ways = 0;
|
||||
for (int first = pre; first <= rest; first++) {
|
||||
ways += process(first, rest - first);
|
||||
}
|
||||
return ways;
|
||||
}
|
||||
|
||||
public static int dp1(int n) {
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (n == 1) {
|
||||
return 1;
|
||||
}
|
||||
int[][] dp = new int[n + 1][n + 1];
|
||||
for (int pre = 1; pre <= n; pre++) {
|
||||
dp[pre][0] = 1;
|
||||
dp[pre][pre] = 1;
|
||||
}
|
||||
for (int pre = n - 1; pre >= 1; pre--) {
|
||||
for (int rest = pre + 1; rest <= n; rest++) {
|
||||
int ways = 0;
|
||||
for (int first = pre; first <= rest; first++) {
|
||||
ways += dp[first][rest - first];
|
||||
}
|
||||
dp[pre][rest] = ways;
|
||||
}
|
||||
}
|
||||
return dp[1][n];
|
||||
}
|
||||
|
||||
public static int dp2(int n) {
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (n == 1) {
|
||||
return 1;
|
||||
}
|
||||
int[][] dp = new int[n + 1][n + 1];
|
||||
for (int pre = 1; pre <= n; pre++) {
|
||||
dp[pre][0] = 1;
|
||||
dp[pre][pre] = 1;
|
||||
}
|
||||
for (int pre = n - 1; pre >= 1; pre--) {
|
||||
for (int rest = pre + 1; rest <= n; rest++) {
|
||||
dp[pre][rest] = dp[pre + 1][rest];
|
||||
dp[pre][rest] += dp[pre][rest - pre];
|
||||
}
|
||||
}
|
||||
return dp[1][n];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int test = 39;
|
||||
System.out.println(ways(test));
|
||||
System.out.println(dp1(test));
|
||||
System.out.println(dp2(test));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package 第01期_test;
|
||||
|
||||
public class Code03_SubMatrixMaxSum {
|
||||
|
||||
public static int maxSum(int[][] m) {
|
||||
if (m == null || m.length == 0 || m[0].length == 0) {
|
||||
return 0;
|
||||
}
|
||||
// O(N^2 * M)
|
||||
int N = m.length;
|
||||
int M = m[0].length;
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < N; i++) {
|
||||
// i~j
|
||||
int[] s = new int[M];
|
||||
for (int j = i; j < N; j++) {
|
||||
for (int k = 0; k < M; k++) {
|
||||
s[k] += m[j][k];
|
||||
}
|
||||
max = Math.max(max, maxSubArray(s));
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static int maxSubArray(int[] arr) {
|
||||
if (arr == null || arr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int max = Integer.MIN_VALUE;
|
||||
int cur = 0;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
cur += arr[i];
|
||||
max = Math.max(max, cur);
|
||||
cur = cur < 0 ? 0 : cur;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
// 本题测试链接 : https://leetcode-cn.com/problems/max-submatrix-lcci/
|
||||
public static int[] getMaxMatrix(int[][] m) {
|
||||
int N = m.length;
|
||||
int M = m[0].length;
|
||||
int max = Integer.MIN_VALUE;
|
||||
int cur = 0;
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
int c = 0;
|
||||
int d = 0;
|
||||
for (int i = 0; i < N; i++) {
|
||||
int[] s = new int[M];
|
||||
for (int j = i; j < N; j++) {
|
||||
cur = 0;
|
||||
int begin = 0;
|
||||
for (int k = 0; k < M; k++) {
|
||||
s[k] += m[j][k];
|
||||
cur += s[k];
|
||||
if (max < cur) {
|
||||
max = cur;
|
||||
a = i;
|
||||
b = begin;
|
||||
c = j;
|
||||
d = k;
|
||||
}
|
||||
if (cur < 0) {
|
||||
cur = 0;
|
||||
begin = k + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new int[] { a, b, c, d };
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package 第01期_test;
|
||||
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
// 本题测试链接 : https://leetcode.com/problems/trapping-rain-water-ii/
|
||||
public class Code03_TrappingRainWaterII {
|
||||
|
||||
public static class Node {
|
||||
public int value;
|
||||
public int row;
|
||||
public int col;
|
||||
|
||||
public Node(int v, int r, int c) {
|
||||
value = v;
|
||||
row = r;
|
||||
col = c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static int trapRainWater(int[][] heightMap) {
|
||||
if (heightMap == null || heightMap.length == 0 || heightMap[0] == null || heightMap[0].length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int N = heightMap.length;
|
||||
int M = heightMap[0].length;
|
||||
boolean[][] isEnter = new boolean[N][M];
|
||||
PriorityQueue<Node> heap = new PriorityQueue<>((a, b) -> a.value - b.value);
|
||||
for (int col = 0; col < M - 1; col++) {
|
||||
isEnter[0][col] = true;
|
||||
heap.add(new Node(heightMap[0][col], 0, col));
|
||||
}
|
||||
for (int row = 0; row < N - 1; row++) {
|
||||
isEnter[row][M - 1] = true;
|
||||
heap.add(new Node(heightMap[row][M - 1], row, M - 1));
|
||||
}
|
||||
for (int col = M - 1; col > 0; col--) {
|
||||
isEnter[N - 1][col] = true;
|
||||
heap.add(new Node(heightMap[N - 1][col], N - 1, col));
|
||||
}
|
||||
for (int row = N - 1; row > 0; row--) {
|
||||
isEnter[row][0] = true;
|
||||
heap.add(new Node(heightMap[row][0], row, 0));
|
||||
}
|
||||
int water = 0;
|
||||
int max = 0;
|
||||
while (!heap.isEmpty()) {
|
||||
Node cur = heap.poll();
|
||||
max = Math.max(max, cur.value);
|
||||
int r = cur.row;
|
||||
int c = cur.col;
|
||||
if (r > 0 && !isEnter[r - 1][c]) {
|
||||
water += Math.max(0, max - heightMap[r - 1][c]);
|
||||
isEnter[r - 1][c] = true;
|
||||
heap.add(new Node(heightMap[r - 1][c], r - 1, c));
|
||||
}
|
||||
if (r < N - 1 && !isEnter[r + 1][c]) {
|
||||
water += Math.max(0, max - heightMap[r + 1][c]);
|
||||
isEnter[r + 1][c] = true;
|
||||
heap.add(new Node(heightMap[r + 1][c], r + 1, c));
|
||||
}
|
||||
if (c > 0 && !isEnter[r][c - 1]) {
|
||||
water += Math.max(0, max - heightMap[r][c - 1]);
|
||||
isEnter[r][c - 1] = true;
|
||||
heap.add(new Node(heightMap[r][c - 1], r, c - 1));
|
||||
}
|
||||
if (c < M - 1 && !isEnter[r][c + 1]) {
|
||||
water += Math.max(0, max - heightMap[r][c + 1]);
|
||||
isEnter[r][c + 1] = true;
|
||||
heap.add(new Node(heightMap[r][c + 1], r, c + 1));
|
||||
}
|
||||
}
|
||||
return water;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package 第01期_test;
|
||||
|
||||
//leetcode 188
|
||||
public class Code04_BestTimeToBuyAndSellStockIV {
|
||||
|
||||
public static int maxProfit(int K, int[] prices) {
|
||||
if (prices == null || prices.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int N = prices.length;
|
||||
if (K >= N / 2) {
|
||||
return allTrans(prices);
|
||||
}
|
||||
int[][] dp = new int[K + 1][N];
|
||||
int ans = 0;
|
||||
for (int tran = 1; tran <= K; tran++) {
|
||||
int pre = dp[tran][0];
|
||||
int best = pre - prices[0];
|
||||
for (int index = 1; index < N; index++) {
|
||||
pre = dp[tran - 1][index];
|
||||
dp[tran][index] = Math.max(dp[tran][index - 1], prices[index] + best);
|
||||
best = Math.max(best, pre - prices[index]);
|
||||
ans = Math.max(dp[tran][index], ans);
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static int allTrans(int[] prices) {
|
||||
int ans = 0;
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
ans += Math.max(prices[i] - prices[i - 1], 0);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// 课上写的版本,对了
|
||||
public static int maxProfit2(int K, int[] arr) {
|
||||
if (arr == null || arr.length == 0 || K < 1) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
if (K >= N / 2) {
|
||||
return allTrans(arr);
|
||||
}
|
||||
int[][] dp = new int[N][K + 1];
|
||||
// dp[...][0] = 0
|
||||
// dp[0][...] = arr[0.0] 0
|
||||
for (int j = 1; j <= K; j++) {
|
||||
// dp[1][j]
|
||||
int p1 = dp[0][j];
|
||||
int best = Math.max(dp[1][j - 1] - arr[1], dp[0][j - 1] - arr[0]);
|
||||
dp[1][j] = Math.max(p1, best + arr[1]);
|
||||
// dp[1][j] 准备好一些枚举,接下来准备好的枚举
|
||||
for (int i = 2; i < N; i++) {
|
||||
p1 = dp[i - 1][j];
|
||||
int newP = dp[i][j - 1] - arr[i];
|
||||
best = Math.max(newP, best);
|
||||
dp[i][j] = Math.max(p1, best + arr[i]);
|
||||
}
|
||||
}
|
||||
return dp[N - 1][K];
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package 第01期_test;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
// 本题测试链接 : https://leetcode.com/problems/distinct-subsequences-ii/
|
||||
public class Code05_DistinctSubseqValue {
|
||||
|
||||
public static int distinctSubseqII(String s) {
|
||||
if (s == null || s.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
int m = 1000000007;
|
||||
char[] str = s.toCharArray();
|
||||
int[] count = new int[26];
|
||||
int all = 1; // 算空集
|
||||
for (char x : str) {
|
||||
int add = (all - count[x - 'a'] + m) % m;
|
||||
all = (all + add) % m;
|
||||
count[x - 'a'] = (count[x - 'a'] + add) % m;
|
||||
}
|
||||
return all - 1;
|
||||
}
|
||||
|
||||
public static int zuo(String s) {
|
||||
if (s == null || s.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
int m = 1000000007;
|
||||
char[] str = s.toCharArray();
|
||||
HashMap<Character, Integer> map = new HashMap<>();
|
||||
int all = 1; // 一个字符也没遍历的时候,有空集
|
||||
for (char x : str) {
|
||||
int newAdd = all;
|
||||
// int curAll = all + newAdd - (map.containsKey(x) ? map.get(x) : 0);
|
||||
int curAll = all;
|
||||
curAll = (curAll + newAdd) % m;
|
||||
curAll = (curAll - (map.containsKey(x) ? map.get(x) : 0) + m) % m;
|
||||
all = curAll;
|
||||
map.put(x, newAdd);
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String s = "bccaccbaabbc";
|
||||
System.out.println(distinctSubseqII(s) + 1);
|
||||
System.out.println(zuo(s));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package 第01期_test;
|
||||
|
||||
public class Code05_LongestIncreasingPath {
|
||||
|
||||
public static int longestIncreasingPath1(int[][] matrix) {
|
||||
int ans = 0;
|
||||
int N = matrix.length;
|
||||
int M = matrix[0].length;
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (int j = 0; j < M; j++) {
|
||||
ans = Math.max(ans, process1(matrix, i, j));
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// 从m[i][j]开始走,走出来的最长递增链,返回!
|
||||
public static int process1(int[][] m, int i, int j) {
|
||||
int up = i > 0 && m[i][j] < m[i - 1][j] ? process1(m, i - 1, j) : 0;
|
||||
int down = i < (m.length - 1) && m[i][j] < m[i + 1][j] ? process1(m, i + 1, j) : 0;
|
||||
int left = j > 0 && m[i][j] < m[i][j - 1] ? process1(m, i, j - 1) : 0;
|
||||
int right = j < (m[0].length - 1) && m[i][j] < m[i][j + 1] ? process1(m, i, j + 1) : 0;
|
||||
return Math.max(Math.max(up, down), Math.max(left, right)) + 1;
|
||||
}
|
||||
|
||||
public static int longestIncreasingPath2(int[][] matrix) {
|
||||
int ans = 0;
|
||||
int N = matrix.length;
|
||||
int M = matrix[0].length;
|
||||
int[][] dp = new int[N][M];
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (int j = 0; j < M; j++) {
|
||||
ans = Math.max(ans, process2(matrix, i, j, dp));
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// 从m[i][j]开始走,走出来的最长递增链,返回!
|
||||
public static int process2(int[][] m, int i, int j, int[][] dp) {
|
||||
if (dp[i][j] != 0) {
|
||||
return dp[i][j];
|
||||
}
|
||||
// (i,j)不越界
|
||||
int up = i > 0 && m[i][j] < m[i - 1][j] ? process2(m, i - 1, j, dp) : 0;
|
||||
int down = i < (m.length - 1) && m[i][j] < m[i + 1][j] ? process2(m, i + 1, j, dp) : 0;
|
||||
int left = j > 0 && m[i][j] < m[i][j - 1] ? process2(m, i, j - 1, dp) : 0;
|
||||
int right = j < (m[0].length - 1) && m[i][j] < m[i][j + 1] ? process2(m, i, j + 1, dp) : 0;
|
||||
int ans = Math.max(Math.max(up, down), Math.max(left, right)) + 1;
|
||||
dp[i][j] = ans;
|
||||
return ans;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package 第01期_test;
|
||||
|
||||
public class Code05_MinWindowLength {
|
||||
|
||||
public static int minLength(String s1, String s2) {
|
||||
if (s1 == null || s2 == null || s1.length() < s2.length()) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
char[] str1 = s1.toCharArray();
|
||||
char[] str2 = s2.toCharArray();
|
||||
int[] map = new int[256]; // map[37] = 4 37 4次
|
||||
for (int i = 0; i != str2.length; i++) {
|
||||
map[str2[i]]++;
|
||||
}
|
||||
int all = str2.length;
|
||||
|
||||
// [L,R-1] R
|
||||
// [L,R) -> [0,0)
|
||||
int L = 0;
|
||||
int R = 0;
|
||||
int minLen = Integer.MAX_VALUE;
|
||||
while (R != str1.length) {
|
||||
map[str1[R]]--;
|
||||
if (map[str1[R]] >= 0) {
|
||||
all--;
|
||||
}
|
||||
if (all == 0) { // 还完了
|
||||
while (map[str1[L]] < 0) {
|
||||
map[str1[L++]]++;
|
||||
}
|
||||
// [L..R]
|
||||
minLen = Math.min(minLen, R - L + 1);
|
||||
all++;
|
||||
map[str1[L++]]++;
|
||||
}
|
||||
R++;
|
||||
}
|
||||
return minLen == Integer.MAX_VALUE ? 0 : minLen;
|
||||
}
|
||||
|
||||
// 测试链接 : https://leetcode.com/problems/minimum-window-substring/
|
||||
public static String minWindow(String s, String t) {
|
||||
if (s.length() < t.length()) {
|
||||
return "";
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
char[] target = t.toCharArray();
|
||||
int[] map = new int[256];
|
||||
for (char cha : target) {
|
||||
map[cha]++;
|
||||
}
|
||||
int all = target.length;
|
||||
int L = 0;
|
||||
int R = 0;
|
||||
int minLen = Integer.MAX_VALUE;
|
||||
int ansl = -1;
|
||||
int ansr = -1;
|
||||
while (R != str.length) {
|
||||
map[str[R]]--;
|
||||
if (map[str[R]] >= 0) {
|
||||
all--;
|
||||
}
|
||||
if (all == 0) {
|
||||
while (map[str[L]] < 0) {
|
||||
map[str[L++]]++;
|
||||
}
|
||||
if (minLen > R - L + 1) {
|
||||
minLen = R - L + 1;
|
||||
ansl = L;
|
||||
ansr = R;
|
||||
}
|
||||
all++;
|
||||
map[str[L++]]++;
|
||||
}
|
||||
R++;
|
||||
}
|
||||
return minLen == Integer.MAX_VALUE ? "" : s.substring(ansl, ansr + 1);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package 第01期_test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
// 本题测试链接 : https://leetcode.com/problems/closest-subsequence-sum/
|
||||
// 本题数据量描述:
|
||||
// 1 <= nums.length <= 40
|
||||
// -10^7 <= nums[i] <= 10^7
|
||||
// -10^9 <= goal <= 10^9
|
||||
// 通过这个数据量描述可知,需要用到分治,因为数组长度不大
|
||||
// 而值很大,用动态规划的话,表会爆
|
||||
public class Code06_ClosestSubsequenceSum {
|
||||
|
||||
public static int[] l = new int[1 << 20];
|
||||
public static int[] r = new int[1 << 20];
|
||||
|
||||
public static int minAbsDifference(int[] nums, int goal) {
|
||||
if (nums == null || nums.length == 0) {
|
||||
return goal;
|
||||
}
|
||||
int le = process(nums, 0, nums.length >> 1, 0, 0, l);
|
||||
int re = process(nums, nums.length >> 1, nums.length, 0, 0, r);
|
||||
Arrays.sort(l, 0, le);
|
||||
Arrays.sort(r, 0, re--);
|
||||
int ans = Math.abs(goal);
|
||||
for (int i = 0; i < le; i++) {
|
||||
int rest = goal - l[i];
|
||||
while (re > 0 && Math.abs(rest - r[re - 1]) <= Math.abs(rest - r[re])) {
|
||||
re--;
|
||||
}
|
||||
ans = Math.min(ans, Math.abs(rest - r[re]));
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static int process(int[] nums, int index, int end, int sum, int fill, int[] arr) {
|
||||
if (index == end) {
|
||||
arr[fill++] = sum;
|
||||
} else {
|
||||
fill = process(nums, index + 1, end, sum, fill, arr);
|
||||
fill = process(nums, index + 1, end, sum + nums[index], fill, arr);
|
||||
}
|
||||
return fill;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package 第01期_test;
|
||||
|
||||
// 本题测试链接 : https://leetcode.com/problems/shortest-unsorted-continuous-subarray/
|
||||
public class Code07_MinLengthForSort {
|
||||
|
||||
public static int findUnsortedSubarray(int[] nums) {
|
||||
if (nums == null || nums.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
int N = nums.length;
|
||||
int right = -1;
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (max > nums[i]) {
|
||||
right = i;
|
||||
}
|
||||
max = Math.max(max, nums[i]);
|
||||
}
|
||||
int min = Integer.MAX_VALUE;
|
||||
int left = N;
|
||||
for (int i = N - 1; i >= 0; i--) {
|
||||
if (min < nums[i]) {
|
||||
left = i;
|
||||
}
|
||||
min = Math.min(min, nums[i]);
|
||||
}
|
||||
return Math.max(0, right - left + 1);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package 第01期_test;
|
||||
|
||||
public class Problem_0152_MaximumProductSubarray {
|
||||
|
||||
|
||||
public static double max(double[] arr) {
|
||||
if(arr == null || arr.length == 0) {
|
||||
return 0; // 报错!
|
||||
}
|
||||
int n = arr.length;
|
||||
// 上一步的最大
|
||||
double premax = arr[0];
|
||||
// 上一步的最小
|
||||
double premin = arr[0];
|
||||
double ans = arr[0];
|
||||
for(int i = 1; i < n; i++) {
|
||||
double p1 = arr[i];
|
||||
double p2 = arr[i] * premax;
|
||||
double p3 = arr[i] * premin;
|
||||
double curmax = Math.max(Math.max(p1, p2), p3);
|
||||
double curmin = Math.min(Math.min(p1, p2), p3);
|
||||
ans = Math.max(ans, curmax);
|
||||
premax = curmax;
|
||||
premin = curmin;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int maxProduct(int[] nums) {
|
||||
int ans = nums[0];
|
||||
int min = nums[0];
|
||||
int max = nums[0];
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
int curmin = Math.min(nums[i], Math.min(min * nums[i], max * nums[i]));
|
||||
int curmax = Math.max(nums[i], Math.max(min * nums[i], max * nums[i]));
|
||||
min = curmin;
|
||||
max = curmax;
|
||||
ans = Math.max(ans, max);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package 第01期_test;
|
||||
|
||||
public class Problem_0213_HouseRobberII {
|
||||
|
||||
// arr 长度大于等于1
|
||||
public static int pickMaxSum(int[] arr) {
|
||||
int n = arr.length;
|
||||
// dp[i] : arr[0..i]范围上,随意选择,但是,任何两数不能相邻。得到的最大累加和是多少?
|
||||
int[] dp = new int[n];
|
||||
dp[0] = arr[0];
|
||||
dp[1] = Math.max(arr[0], arr[1]);
|
||||
for (int i = 2; i < n; i++) {
|
||||
int p1 = arr[i];
|
||||
int p2 = dp[i - 1];
|
||||
int p3 = arr[i] + dp[i - 2];
|
||||
dp[i] = Math.max(p1, Math.max(p2, p3));
|
||||
}
|
||||
return dp[n - 1];
|
||||
}
|
||||
|
||||
public static int rob(int[] nums) {
|
||||
if (nums == null || nums.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (nums.length == 1) {
|
||||
return nums[0];
|
||||
}
|
||||
if (nums.length == 2) {
|
||||
return Math.max(nums[0], nums[1]);
|
||||
}
|
||||
int pre2 = nums[0];
|
||||
int pre1 = Math.max(nums[0], nums[1]);
|
||||
for (int i = 2; i < nums.length - 1; i++) {
|
||||
int tmp = Math.max(pre1, nums[i] + pre2);
|
||||
pre2 = pre1;
|
||||
pre1 = tmp;
|
||||
}
|
||||
int ans1 = pre1;
|
||||
pre2 = nums[1];
|
||||
pre1 = Math.max(nums[1], nums[2]);
|
||||
for (int i = 3; i < nums.length; i++) {
|
||||
int tmp = Math.max(pre1, nums[i] + pre2);
|
||||
pre2 = pre1;
|
||||
pre1 = tmp;
|
||||
}
|
||||
int ans2 = pre1;
|
||||
return Math.max(ans1, ans2);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue