【发布时间】:2014-06-13 14:29:03
【问题描述】:
我有一个排序矩阵中第 n 个最大元素的代码(按行和列递增的顺序排序)
我在执行代码中的 (findNextElement) 部分时遇到了一些问题 即,如果该行已用尽,则向上一行并获取其中的下一个元素。
我已经做到了,但是代码看起来有点复杂。 (我的代码可以正常工作并正确生成输出)我将在这里发布我的代码
k 是第 K 个最大的元素 m, n 是矩阵维度(目前只支持 NxN 矩阵,但可以修改为支持 MxN)
public int findkthLargestElement(int[][] input, int k, int m, int n) {
if (m <=1 || n <= 1 || k > m * n) {
return Integer.MIN_VALUE;
}
int i = 0;
int j = 0;
if (k < m && k < n) {
i = m - k;
j = n - k;
}
PriorityQueue<Element> maxQueue = new PriorityQueue(m, new Comparator<Element>() {
@Override
public int compare(Element a, Element b) {
return b.value - a.value;
}
});
Map<Integer, Integer> colMap = new HashMap<Integer, Integer>();
for (int row = i; row < m; row++) {
Element e = new Element(input[row][n - 1], row, n - 1);
colMap.put(row, n - 1);
maxQueue.add(e);
}
Element largest = new Element(0, 0, 0);
for (int l = 0; l < k; l++) {
largest = maxQueue.poll();
int row = largest.row;
colMap.put(row, colMap.get(row) - 1);
int col = colMap.get(row);
while (col < j && row > i) {
row = row - 1;
colMap.put(row, colMap.get(row) - 1);
col = Math.max(0, colMap.get(row));
}
Element nextLargest = new Element(input[row][Math.max(0, col)], row, Math.max(0, col));
maxQueue.add(nextLargest);
}
return largest.value;
}
我在 for 循环中需要一些帮助,请建议我一个更好的方法来完成任务。
我的代码在这里运行 http://ideone.com/wIeZSo
好的,我找到了一种简单有效的方法来完成这项工作,我将 for 循环更改为 ths
for (int l = 0; l < k; l++) {
largest = maxQueue.poll();
int row = largest.row;
colMap.put(row, colMap.get(row) - 1);
int col = colMap.get(row);
if (col < j) {
continue;
}
Element nextLargest = new Element(input[row][Math.max(0, col)], row, Math.max(0, col));
maxQueue.add(nextLargest);
}
如果我们对某一列感到筋疲力尽,那么我们不会再添加任何项目,直到我们从其他列中找到一个元素。
这也适用于仅按行而非按列排序的矩阵。
【问题讨论】:
-
你或许应该解释一下为什么这个方法的实现可能不只是
int i=m*n-1-(k-1);return input[i/n][i%n];。很可能是因为矩阵中可能有 相等 个元素...? -
@Marco13 我从来没有想过你提出的解决方案!但是是的,这些值可以重复。
标签: java algorithm sorting data-structures matrix