diff --git a/src/class24/Code01_SlidingWindowMaxArray.java b/src/class24/Code01_SlidingWindowMaxArray.java index 23671dc..071eba7 100644 --- a/src/class24/Code01_SlidingWindowMaxArray.java +++ b/src/class24/Code01_SlidingWindowMaxArray.java @@ -4,28 +4,43 @@ import java.util.LinkedList; public class Code01_SlidingWindowMaxArray { + // 暴力的对数器方法 + public static int[] right(int[] arr, int w) { + if (arr == null || w < 1 || arr.length < w) { + return null; + } + int[] res = new int[arr.length - w + 1]; + int index = 0; + int L = 0; + int R = w - 1; + while (R < arr.length) { + int max = arr[L]; + for (int i = L + 1; i <= R; i++) { + max = Math.max(max, arr[i]); + + } + res[index++] = max; + L++; + R++; + } + return res; + } + public static int[] getMaxWindow(int[] arr, int w) { if (arr == null || w < 1 || arr.length < w) { return null; } - // 其中放的是位置,头代表 (大->小)尾 LinkedList qmax = new LinkedList(); int[] res = new int[arr.length - w + 1]; int index = 0; - // L...R - // i - for (int R = 0; R < arr.length; R++) { // 当前让 i -> [i] 进窗口 , i 就是 r - // R -> 值 可以放在比他大的数后,或者空 + for (int R = 0; R < arr.length; R++) { while (!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[R]) { qmax.pollLast(); } qmax.addLast(R); - // 数进来了 - // 如果窗口没有形成W的长度之前,不弹出数字的 if (qmax.peekFirst() == R - w) { qmax.pollFirst(); } - // 以上窗口更新做完了 if (R >= w - 1) { res[index++] = arr[qmax.peekFirst()]; } @@ -33,28 +48,6 @@ public class Code01_SlidingWindowMaxArray { return res; } - // for test - public static int[] rightWay(int[] arr, int w) { - if (arr == null || w < 1 || arr.length < w) { - return null; - } - int[] res = new int[arr.length - w + 1]; - int index = 0; - int L = 0; - int R = w - 1; - while (R < arr.length) { - int max = arr[L]; - for (int i = L + 1; i <= R; i++) { - max = Math.max(max, arr[i]); - - } - res[index++] = max; - L++; - R++; - } - return res; - } - // for test public static int[] generateRandomArray(int maxSize, int maxValue) { int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; @@ -92,7 +85,7 @@ public class Code01_SlidingWindowMaxArray { int[] arr = generateRandomArray(maxSize, maxValue); int w = (int) (Math.random() * (arr.length + 1)); int[] ans1 = getMaxWindow(arr, w); - int[] ans2 = rightWay(arr, w); + int[] ans2 = right(arr, w); if (!isEqual(ans1, ans2)) { System.out.println("Oops!"); } diff --git a/src/class24/Code02_AllLessNumSubArray.java b/src/class24/Code02_AllLessNumSubArray.java index 40f6107..7bbd5de 100644 --- a/src/class24/Code02_AllLessNumSubArray.java +++ b/src/class24/Code02_AllLessNumSubArray.java @@ -4,62 +4,71 @@ import java.util.LinkedList; public class Code02_AllLessNumSubArray { - public static int getNum(int[] arr, int num) { - if (arr == null || arr.length == 0) { + // 暴力的对数器方法 + public static int right(int[] arr, int sum) { + if (arr == null || arr.length == 0 || sum < 0) { return 0; } - LinkedList qmin = new LinkedList(); - LinkedList qmax = new LinkedList(); - int L = 0; - int R = 0; - // [L..R) -> [0,0) 窗口内无数 [1,1) - // [0,1) -> [0~0] - int res = 0; - while (L < arr.length) { // L是开头位置,尝试每一个开头 - - // 如果此时窗口的开头是L,下面的while工作:R向右扩到违规为止 - - while (R < arr.length) { // R是最后一个达标位置的再下一个 - while (!qmin.isEmpty() && arr[qmin.peekLast()] >= arr[R]) { - qmin.pollLast(); + 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]); } - qmin.addLast(R); - // R -> arr[R], - while (!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[R]) { - qmax.pollLast(); + if (max - min <= sum) { + count++; } - qmax.addLast(R); + } + } + return count; + } - if (arr[qmax.getFirst()] - arr[qmin.getFirst()] > num) { + 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 maxWindow = new LinkedList<>(); + LinkedList 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++; } - R++; } - - // R是最后一个达标位置的再下一个,第一个违规的位置 - res += R - L; - - if (qmin.peekFirst() == L) { - qmin.pollFirst(); + count += R - L; + if (maxWindow.peekFirst() == L) { + maxWindow.pollFirst(); } - if (qmax.peekFirst() == L) { - qmax.pollFirst(); + if (minWindow.peekFirst() == L) { + minWindow.pollFirst(); } - - L++; - } - return res; + return count; } // for test - public static int[] getRandomArray(int len) { - if (len < 0) { - return null; - } + 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() * 10); + arr[i] = (int) (Math.random() * (maxValue + 1)) - (int) (Math.random() * (maxValue + 1)); } return arr; } @@ -75,10 +84,25 @@ public class Code02_AllLessNumSubArray { } public static void main(String[] args) { - int[] arr = getRandomArray(30); - int num = 5; - printArray(arr); - System.out.println(getNum(arr, num)); + 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("测试结束"); }