You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2022_03_2_week;
// 来自微软
// 给定一个正数数组arr长度为N依次代表N个任务的难度给定一个正数k
// 你只能从0任务开始依次处理到N-1号任务结束就是一定要从左往右处理任务
// 只不过难度差距绝对值不超过k的任务可以在一天之内都完成
// 返回完成所有任务的最少天数
public class Code06_JobMinDays {
public static int minDays1(int[] arr, int k) {
int n = arr.length;
int[] dp = new int[n];
dp[0] = 1;
for (int i = 1; i < n; i++) {
dp[i] = dp[i - 1] + 1;
int min = arr[i];
int max = arr[i];
for (int j = i - 1; j >= 0; j--) {
min = Math.min(min, arr[j]);
max = Math.max(max, arr[j]);
if (max - min <= k) {
dp[i] = Math.min(dp[i], 1 + (j - 1 >= 0 ? dp[j - 1] : 0));
} else {
break;
}
}
}
return dp[n - 1];
}
public static int minDays2(int[] arr, int k) {
int n = arr.length;
int[] dp = new int[n];
int[] windowMax = new int[n];
int[] windowMin = new int[n];
int maxL = 0;
int maxR = 0;
int minL = 0;
int minR = 0;
int L = 0;
for (int i = 0; i < n; i++) {
while (maxL < maxR && arr[windowMax[maxR - 1]] <= arr[i]) {
maxR--;
}
windowMax[maxR++] = i;
while (minL < minR && arr[windowMin[minR - 1]] >= arr[i]) {
minR--;
}
windowMin[minR++] = i;
while (arr[windowMax[maxL]] - arr[windowMin[minL]] > k) {
if (windowMax[maxL] == L) {
maxL++;
}
if (windowMin[minL] == L) {
minL++;
}
L++;
}
dp[i] = 1 + (L - 1 >= 0 ? dp[L - 1] : 0);
}
return dp[n - 1];
}
// 为了测试
public static int[] randomArray(int n, int v) {
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = (int) (Math.random() * v);
}
return arr;
}
// 为了测试
public static void main(String[] args) {
int len = 50;
int value = 20;
int testTime = 20000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int n = (int) (Math.random() * len) + 1;
int[] arr = randomArray(n, value);
int k = (int) (Math.random() * value);
int ans1 = minDays1(arr, k);
int ans2 = minDays2(arr, k);
if (ans1 != ans2) {
System.out.println("出错了!");
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
System.out.println("k = " + k);
System.out.println(ans1);
System.out.println(ans2);
break;
}
}
System.out.println("测试结束");
}
}