diff --git a/src/main/java/git/snippet/heap/Code_DistanceLessK.java b/src/main/java/git/snippet/heap/DistanceLessK.java similarity index 89% rename from src/main/java/git/snippet/heap/Code_DistanceLessK.java rename to src/main/java/git/snippet/heap/DistanceLessK.java index 81fe98af7204cd3a56afe1122ddf8e9dba7b0550..40b22b7f9c3e3fec3b04a06cbbf7b630faff6df4 100644 --- a/src/main/java/git/snippet/heap/Code_DistanceLessK.java +++ b/src/main/java/git/snippet/heap/DistanceLessK.java @@ -7,7 +7,7 @@ import java.util.PriorityQueue; // 几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离一定不超过k,并且k相对于数组长度来说是比较小的。 // 请选择一个合适的排序策略,对这个数组进行排序。(从小到大) // tips: 加k个数进堆,然后再加入一个,弹出一个,最后堆里面剩下的继续弹出即可 时间复杂度:O(N*logK) -public class Code_DistanceLessK { +public class DistanceLessK { public static void sortedArrDistanceLessK(int[] arr, int k) { k = Math.min(arr.length - 1, k); PriorityQueue heap = new PriorityQueue<>(); @@ -20,7 +20,9 @@ public class Code_DistanceLessK { for (; i < arr.length; i++) { heap.offer(arr[i]); // 移动一定不会超过K次 - arr[index++] = heap.poll(); + if (!heap.isEmpty()) { + arr[index++] = heap.poll(); + } } while (!heap.isEmpty()) { arr[index++] = heap.poll(); diff --git a/src/test/java/git/snippet/common/Generator.java b/src/test/java/git/snippet/common/Generator.java index 6dbf2586a8b1ed3f6c84d5501830fff273c3098f..50f1b1a4b7304e0e09788193925696da6498b269 100644 --- a/src/test/java/git/snippet/common/Generator.java +++ b/src/test/java/git/snippet/common/Generator.java @@ -1,6 +1,34 @@ package git.snippet.common; +import java.util.Arrays; + public class Generator { + // for test + // 几乎有序的数组排序测试 + public static int[] randomArrayNoMoveMoreK(int maxSize, int maxValue, int K) { + int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; + for (int i = 0; i < arr.length; i++) { + arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); + } + // 先排个序 + Arrays.sort(arr); + // 然后开始随意交换,但是保证每个数距离不超过K + // swap[i] == true, 表示i位置已经参与过交换 + // swap[i] == false, 表示i位置没有参与过交换 + boolean[] isSwap = new boolean[arr.length]; + for (int i = 0; i < arr.length; i++) { + int j = Math.min(i + (int) (Math.random() * (K + 1)), arr.length - 1); + if (!isSwap[i] && !isSwap[j]) { + isSwap[i] = true; + isSwap[j] = true; + int tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + } + return arr; + } + // for test public static int[] generateRandomArray(int maxSize, int maxValue) { // Math.random() -> [0,1) diff --git a/src/test/java/git/snippet/heap/Code_DistanceLessKTest.java b/src/test/java/git/snippet/heap/Code_DistanceLessKTest.java deleted file mode 100644 index a8e91063a5a4a7334a56b4689a90cdb57c3a59fa..0000000000000000000000000000000000000000 --- a/src/test/java/git/snippet/heap/Code_DistanceLessKTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package git.snippet.heap; - -import git.snippet.common.Generator; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; - -import static org.junit.jupiter.api.Assertions.*; - -@DisplayName("几乎有序的数组排序测试") -public class Code_DistanceLessKTest { - - @Test - @DisplayName("几乎有序的数组排序测试") - public void sortedArrDistanceLessK() { - int testTime = 500000; - int maxSize = 100; - int maxValue = 100; - for (int i = 0; i < testTime; i++) { - int k = (int) (Math.random() * maxSize) + 1; - int[] arr = randomArrayNoMoveMoreK(maxSize, maxValue, k); - int[] arr1 = Generator.copyArray(arr); - int[] arr2 = Generator.copyArray(arr); - Code_DistanceLessK.sortedArrDistanceLessK(arr1, k); - Arrays.sort(arr2); - Assertions.assertArrayEquals(arr1, arr2); - } - } - - - // for test - public static int[] randomArrayNoMoveMoreK(int maxSize, int maxValue, int K) { - int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; - for (int i = 0; i < arr.length; i++) { - arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); - } - // 先排个序 - Arrays.sort(arr); - // 然后开始随意交换,但是保证每个数距离不超过K - // swap[i] == true, 表示i位置已经参与过交换 - // swap[i] == false, 表示i位置没有参与过交换 - boolean[] isSwap = new boolean[arr.length]; - for (int i = 0; i < arr.length; i++) { - int j = Math.min(i + (int) (Math.random() * (K + 1)), arr.length - 1); - if (!isSwap[i] && !isSwap[j]) { - isSwap[i] = true; - isSwap[j] = true; - int tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; - } - } - return arr; - } - -} \ No newline at end of file diff --git a/src/test/java/git/snippet/heap/DistanceLessKTest.java b/src/test/java/git/snippet/heap/DistanceLessKTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0281e689a83d3422ba374d7d35dd868ca4554073 --- /dev/null +++ b/src/test/java/git/snippet/heap/DistanceLessKTest.java @@ -0,0 +1,29 @@ +package git.snippet.heap; + +import git.snippet.common.Generator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +@DisplayName("几乎有序的数组排序测试") +public class DistanceLessKTest { + + @Test + @DisplayName("几乎有序的数组排序测试") + public void sortedArrDistanceLessK() { + int testTime = 500000; + int maxSize = 100; + int maxValue = 100; + for (int i = 0; i < testTime; i++) { + int k = (int) (Math.random() * maxSize) + 1; + int[] arr = Generator.randomArrayNoMoveMoreK(maxSize, maxValue, k); + int[] arr1 = Generator.copyArray(arr); + int[] arr2 = Generator.copyArray(arr); + DistanceLessK.sortedArrDistanceLessK(arr1, k); + Arrays.sort(arr2); + Assertions.assertArrayEquals(arr1, arr2); + } + } +} \ No newline at end of file