英文:
Find K Smallest Elements in an Array
问题
我想在数组中找到最小的 K 个元素,我已经基本上将数组排序成了一个最小堆结构,但输出结果仍然是错误的。
这是我的输入:
arr = [9,4,7,1,-2,6,5]
k = 3
这是代码部分:
public static int[] findKSmallest(int[] arr, int k) {
int[] result = new int[k];
int heapSize = arr.length;
// 写入 - 你的 - 代码部分
for (int i = (heapSize - 1) / 2; i >= 0; i--) {
minHeap(arr, i, heapSize);
}
for (int j = 0; j < k; j++) {
result[j] = arr[j];
}
return result;
}
public static void minHeap(int[] arr, int index, int heapSize) {
int smallest = index;
while (smallest < heapSize / 2) {
int left = (2 * index) + 1; // 比索引大 1
int right = (2 * index) + 2; // 比索引大 2
if (left < heapSize && arr[left] < arr[index]) {
smallest = left;
}
if (right < heapSize && arr[right] < arr[smallest]) {
smallest = right;
}
if (smallest != index) {
int temp = arr[index];
arr[index] = arr[smallest];
arr[smallest] = temp;
index = smallest;
} else {
break;
}
}
}
这是我期望的输出:
[-2,1,4]
尽管我的输出是:
[-2,1,5]
请问我哪里出错了。
英文:
I want to find the K smallest elements in an array, and I was able to basically sort my array into a min-heap structure but I am still getting the wrong output.
Here are my inputs:
arr = [9,4,7,1,-2,6,5]
k = 3
Here's the Code:
public static int[] findKSmallest(int[] arr, int k) {
int[] result = new int[k];
int heapSize = arr.length;
// Write - Your - Code
for (int i = (heapSize - 1) / 2; i >= 0; i--) {
minHeap(arr, i, heapSize);
}
for (int j = 0; j < k; j++) {
result[j] = arr[j];
}
return result;
}
public static void minHeap(int[] arr, int index, int heapSize) {
int smallest = index;
while (smallest < heapSize / 2) {
int left = (2 * index) + 1; // 1 more than half the index
int right = (2 * index) + 2; // 2 more than half the index
if (left < heapSize && arr[left] < arr[index]) {
smallest = left;
}
if (right < heapSize && arr[right] < arr[smallest]) {
smallest = right;
}
if (smallest != index) {
int temp = arr[index];
arr[index] = arr[smallest];
arr[smallest] = temp;
index = smallest;
} else {
break;
}
}
}
Here is my expected output:
[-2,1,4]
Though my output is:
[-2,1,5]
Please I would like to know where I went wrong.
答案1
得分: 1
构建小顶堆后,您需要提取元素并适当调整树结构。您之前通过索引从数组中获取元素,但这不是堆的工作方式。
我稍微修改了您的 minHeap()
方法,使用了 递归
,您应该检查 arr[smallest] < arr[left]
而不是相反的情况。
public static int[] findKSmallest(int[] arr, int k) {
int[] result = new int[k];
int heapSize = arr.length;
// 写 - 你的 - 代码
for (int i = (heapSize - 1) / 2; i >= 0; i--) {
minHeap(arr, heapSize, i);
}
// 从堆中提取元素
for (int i = heapSize - 1; i > 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
minHeap(arr, 0, i);
}
for (int j = 0; j < k; j++) {
result[j] = arr[j];
}
return result;
}
public static void minHeap(int[] arr, int index, int heapSize) {
int smallest = index;
int left = (2 * index) + 1; // 比索引大1
int right = (2 * index) + 2; // 比索引大2
if (left < heapSize && arr[smallest] < arr[left]) {
smallest = left;
}
if (right < heapSize && arr[smallest] < arr[right]) {
smallest = right;
}
if (smallest != index) {
int temp = arr[index];
arr[index] = arr[smallest];
arr[smallest] = temp;
minHeap(arr, smallest, heapSize);
}
}
希望这有所帮助。如预期的结果是:
[-2, 1, 4]
英文:
After you build your minHeap you have to extract element and appropriately adjust tree. You simply took elements from array by index, which is not how heap works.
I slightly modified your minHeap()
method to use recursion
and you should check arr[smallest] < arr[left]
not the orther way around.
public static int[] findKSmallest(int[] arr, int k) {
int[] result = new int[k];
int heapSize = arr.length;
// Write - Your - Code
for (int i = (heapSize - 1) / 2; i >= 0; i--) {
minHeap(arr, heapSize, i);
}
// extract elements from heap
for (int i = heapSize - 1; i > 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
minHeap(arr, 0, i);
}
for (int j = 0; j < k; j++) {
result[j] = arr[j];
}
return result;
}
public static void minHeap(int[] arr, int index, int heapSize) {
int smallest = index;
int left = (2 * index) + 1; // 1 more than half the index
int right = (2 * index) + 2; // 2 more than half the index
if (left < heapSize && arr[smallest] < arr[left]) {
smallest = left;
}
if (right < heapSize && arr[smallest] < arr[right]) {
smallest = right;
}
if (smallest != index) {
int temp = arr[index];
arr[index] = arr[smallest];
arr[smallest] = temp;
minHeap(arr, smallest, heapSize);
}
}
Hope this helps. As expected the result is:
[-2, 1, 4]
答案2
得分: 0
自从Java 8以来,我们可以对流进行排序
替代代码:
Arrays.stream(arr).sorted().boxed().collect(Collectors.toList()).subList(0, k);
其中:
int[] arr = {9, 4, 7, 1, -2, 6, 5};
int k = 3; // toIndex
上下文中的替代代码和测试代码:
public static void main(String[] args) {
int[] arr = {9, 4, 7, 1, -2, 6, 5};
int k = 3; // toIndex
List<Integer> listResult = Arrays.stream(arr)
.sorted().boxed().collect(Collectors.toList()).subList(0, k);
// 打印列表结果
System.out.println("列表结果输出: " + listResult);
int[] arrayResult = listResult.stream().mapToInt(i -> i).toArray();
// 打印数组结果
List<String> arrayResultAsString = Arrays.stream(arrayResult)
.boxed().map(i -> String.valueOf(i)).collect(Collectors.toList());
System.out.println("数组结果输出: " + arrayResultAsString);
}
输出结果:
列表结果输出: [-2, 1, 4]
数组结果输出: [-2, 1, 4]
英文:
Since Java 8 we can do Sorting stream
Alternative code:
Arrays.stream(arr).sorted().boxed().collect(Collectors.toList()).subList(0, k);
where:
int[] arr = {9,4,7,1,-2,6,5};
int k = 3; // toIndex
Alternative code in context and testbench:
public static void main(String[] args) {
int[] arr = {9, 4, 7, 1, -2, 6, 5};
int k = 3; // toIndex
List<Integer> listResult = Arrays.stream(arr)
.sorted().boxed().collect(Collectors.toList()).subList(0, k);
// print out list result
System.out.println("Output of list result: " + listResult);
int[] arrayResult = listResult.stream().mapToInt(i -> i).toArray();
// print out array result
List<String> arrayResultAsString = Arrays.stream(arrayResult)
.boxed().map(i -> String.valueOf(i)).collect(Collectors.toList());
System.out.println("Output of array result: " + arrayResultAsString);
}
Output:
Output of list result: [-2, 1, 4]
Output of array result: [-2, 1, 4]
答案3
得分: 0
你可以使用 Arrays.stream(int[])
方法:
int[] arr = {9, 4, 7, 1, -2, 6, 5};
int k = 3;
int[] minHeap = Arrays.stream(arr).sorted().limit(k).toArray();
System.out.println(Arrays.toString(minHeap)); // [-2, 1, 4]
英文:
You can use Arrays.stream(int[])
method:
int[] arr = {9, 4, 7, 1, -2, 6, 5};
int k = 3;
int[] minHeap = Arrays.stream(arr).sorted().limit(k).toArray();
System.out.println(Arrays.toString(minHeap)); // [-2, 1, 4]
答案4
得分: 0
如果K相对于数组大小较小,我的建议是使用选择排序,这可能是一个策略设计模式 - 具体取决于K与数组大小的关系,例如可以使用两种程序:对于较小的K,使用选择排序,对于较大的K,使用快速排序。而不是使用设计模式,使用简单的if语句可能也是一个不错的选择,例如选择<=30%<quick。
英文:
If K is relatively small to the array size my recommendation is to use selection sort, so it may be a design pattern Strategy - depending on K to array size relation with for example two procedures: selection sort for small K and quicksort for huge K. Instead of playing with design patterns good may be also simple if statement e.g. selection<=30%<quick
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论