回答
假。
考慮一個簡單的矩陣像這樣的:
1 3 5
2 4 6
7 8 9
9是最大的(第9最小)元素。但是9在A [3,3]和3 + 3!= 9(不管你使用什麼索引慣例,它都不是真的)。
可以解決爲O這個問題(K log n)的時間通過遞增合併的行,具有堆擴充以有效地找到最小元素。
基本上,您將第一列的元素放入堆中並跟蹤它們來自的行。在每一步中,您從堆中移除最小元素,並從它所在的行中推入下一個元素(如果到達行的末尾,則不會推動任何內容)。刪除最小值並添加新元素的成本爲O(log n)。在第j個步驟中,您將刪除j
th的最小元素,因此在完成k
步驟後,完成操作的總成本爲O(k log n)
(其中n是矩陣中的行數)。
對於上面的矩陣,您最初從堆中的1,2,7
開始。您刪除1
並添加3
(因爲第一行是1 3 5
)得到2,3,7
。您刪除2
並添加4
以獲得3,4,7
。刪除3
並添加5
得到4,5,7
。刪除4
並添加6
得到5,6,7
。請注意,我們正在刪除全局排序順序中的元素。你可以看到繼續這個過程將在k次迭代之後產生最小的元素。
(如果基質具有比列更多的行,然後在列進行操作,而不是減少的運行時間。)
這是很好的例子。當矩陣是一個集合。沒有重複元素 – 2013-03-02 21:30:23
很平凡,完成。 – nneonneo 2013-03-02 21:33:47
請檢查我的答案如果我沒有改正。用我的假設 – 2013-03-02 21:35:47
O(k log(k))
溶液。
建立一個minheap。
將
(0,0)
添加到堆中。雖然,我們還沒有找到kth
最小的元素,從堆中刪除頂部元素(x,y)
,並添加接下來的兩個元素[(x+1,y)
和(x,y+1)]
,如果它們以前沒有訪問過。
我們對大小O(k)
,因此複雜的堆做O(k)
操作。
你可以給這個格式嗎?難以辨認的樣子 – StormeHawke 2013-09-23 18:39:28
你確定這是正確的嗎?我的意思是即使我的想法也一樣,只是因爲答案中收到的票數與其他票數不同而感到驚訝,即使您的解決方案的複雜性比另一個更好。 – 2013-09-27 05:41:41
我認爲這是正確的,有專家請確認嗎? – Harry 2014-02-17 07:25:12
k
以n*m
爲界。因此,在O(k*log(k))
中運行的解決方案比O(k)
更差,這實際上是O(n*m)
,這是簡單的搜索。
瑣碎的搜索無法完成這項工作。雖然矩陣按行和列排序,但總體上它們並沒有完全排序。所以,如果你想映射到'n * m',你需要將它們全部讀取,然後將它們全部排序,即'n * m * Log(n * m)' – 2014-04-16 20:07:32
我們實際上並不需要排序來查找那麼第k大。可以使用隨機選擇來完成。長度'n'以'O(n)'運行。長度'n * m'可以在'O(n * m)'中完成。唯一的問題是通過這樣做,我們忽略了矩陣的排序。 – Ehsan 2014-09-29 21:27:27
似乎這只是使用該功能:每行都進行排序,但不使用其列式智能排序功能。
開始從左上角(0,0)遍歷矩陣,並使用二進制堆來存儲「邊界」 - 矩陣的訪問部分與其餘部分之間的邊界。
實現在Java中:
private static class Cell implements Comparable<Cell> {
private final int x;
private final int y;
private final int value;
public Cell(int x, int y, int value) {
this.x = x;
this.y = y;
this.value = value;
}
@Override
public int compareTo(Cell that) {
return this.value - that.value;
}
}
private static int findMin(int[][] matrix, int k) {
int min = matrix[0][0];
PriorityQueue<Cell> frontier = new PriorityQueue<>();
frontier.add(new Cell(0, 0, min));
while (k > 1) {
Cell poll = frontier.remove();
if (poll.y + 1 < matrix[poll.x].length) frontier.add(new Cell(poll.x, poll.y + 1, matrix[poll.x][poll.y + 1]));
if (poll.x + 1 < matrix.length) frontier.add(new Cell(poll.x + 1, poll.y, matrix[poll.x + 1][poll.y]));
if (poll.value > min) {
min = poll.value;
k--;
}
}
return min;
}
隨着人們前面提到的最簡單的方法是建立一個min heap
。下面是使用的PriorityQueue Java實現:
private int kthSmallestUsingHeap(int[][] matrix, int k) {
int n = matrix.length;
// This is not necessary since this is the default Int comparator behavior
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
};
// building a minHeap
PriorityQueue<Integer> pq = new PriorityQueue<>(n*n, comparator);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
pq.add(matrix[i][j]);
}
}
int ans = -1;
// remove the min element k times
for (int i = 0; i < k; i++) {
ans = pq.poll();
}
return ans;
}
//int arr[][] = {{1, 5, 10, 14},
// {2, 7, 12, 16},
// {4, 10, 15, 20},
// {6, 13, 19, 22}
//};
// O(k) Solution
public static int myKthElement(int arr[][], int k) {
int lRow = 1;
int lCol = 0;
int rRow = 0;
int rCol = 1;
int count = 1;
int row = 0;
int col = 0;
if (k == 1) {
return arr[row][col];
}
int n = arr.length;
if (k > n * n) {
return -1;
}
while (count < k) {
count++;
if (arr[lRow][lCol] < arr[rRow][rCol]) {
row = lRow;
col = lCol;
if (lRow < n - 1) {
lRow++;
} else {
if (lCol < n - 1) {
lCol++;
}
if (rRow < n - 1) {
lRow = rRow + 1;
}
}
} else {
row = rRow;
col = rCol;
if (rCol < n - 1) {
rCol++;
} else {
if (rRow < n - 1) {
rRow++;
}
if (lCol < n - 1) {
rCol = lCol + 1;
}
}
}
}
return arr[row][col];
}
請在回答中添加一些內容,以便詳細說明您的方法或解決方案,以便對正在查看答案的任何人進行更好的理解。 – kabirbaidhya 2017-03-22 06:00:29
- 1. 使用QuickSelect第k個最小元素排序矩陣
- 2. 查找未排序數組中的第k個最小元素
- 3. 排列中第k個最大元素
- 4. 第K個最小元素算法
- 5. 找到第k個最小元素
- 6. 如何實現最小堆排序來查找第k個最小元素?
- 7. 在未排序的向量中查找第K個最小元素(迭代式)
- 8. 矩陣的k個連通元素的最大總和
- 9. 在排序中查找數組中第n個最小元素?
- 10. 在二維排序數組中找到k個最小\最大元素
- 11. 算法在推力/ cudpp中找到第k個最小元素
- 12. 在O(log n)中查找第k個最小元素
- 13. numpy矩陣的最大元素/大小?
- 14. 排序K-排序陣列具有最小堆
- 15. 在大小爲N的數組的每k個元素中查找最小元素和第二小元素
- 16. 發現排列第k個最大的元素袋
- 17. 蟒 - 選擇第1列的每個值在排序numpy的矩陣塔2的頂部k個元素
- 18. 找到列表中第K個最大元素的程序
- 19. 在最小堆中查找k個最小元素
- 20. 從A union B找到第k個最小元素
- 21. 找到第2個元素中第k個元素的最大值
- 22. 使用快速排序(Python)查找第k個最小項目
- 23. 使用快速排序的第k個最小數字
- 24. 從矩陣中找出一個非對角線最小元素
- 25. 打印矩陣的排序元素在最快的時尚
- 26. 矩陣與元素的矩陣元素
- 27. k個最大元素
- 28. 使用修改的快速排序從陣列中選擇k個最小元素的運行時錯誤
- 29. 在bst中第k個最小數字
- 30. 如何查找未排序數組或其段中的第k個最小元素?
如何矩陣排序?只有在每一行或每列中的數字增加? – 2013-03-02 21:19:58
是的,每行和每列的數字按升序排列。 – Michael 2013-03-02 21:21:16
想出一個反例來證明陳述是錯誤的是非常容易的。 – NPE 2013-03-02 21:21:26