[leetcode/lintcode 題解] Amazon 面試題:排序矩陣中的從小到大第k個數
輸入:
[
[1 ,5 ,7],
[3 ,7 ,8],
[4 ,8 ,9],
]
k = 4
輸出: 5
樣例 2:
輸入:
[
[1, 2],
[3, 4]
]
k = 3
輸出: 3
演算法:二分
題目中矩陣n行m列,每行每列都是單調的,我們可以按照行或者列做
把n行當成n個數組
即求n個有序數組裡第k小值是多少
如果序列有序,則可以用一種更有效率的查詢方法來查詢序列中的記錄,這就是折半查詢法,又稱為二分搜尋。
折半查詢的基本思想:減少一半的查詢序列的長度,分而治之地進行關鍵字的查詢。他的查詢過程是:先確定待查詢記錄的所在的範圍,然後逐漸縮小查詢的範圍,直至找到該記錄為止(也可能查詢失敗)。- 二分第k小的是多少
- 對於二分出來的x,判斷有多少個元素是小於等於x的
import java.util.Comparator;import java.util.PriorityQueue;
public class Solution {
public long calc(int x, int[][] matrix) {
long num = 0;
for(int i = 0; i < matrix.length; i++) {
int left = -1, right = matrix[i].length, pos = -1;
//二分upper_bound查詢多少個比x大的
while(left + 1 < right) {
int mid = left + (right - left) / 2;
if(matrix[i][mid] > x) {
right = mid;
pos = mid;
} else {
left = mid;
}
}
if(pos == -1) {
num += 0;
} else {
num += matrix[i].length - pos;
}
}
return num;
}
/**
* @param matrix: a matrix of integers
* @param k: An integer
* @return: the kth smallest number in the matrix
*/
public int kthSmallest(int[][] matrix, int k) {
// write your code here
int left = matrix[0][0], right = matrix[0][0];
//矩陣行數
long n = matrix.length;
//矩陣列數
long m = matrix[0].length;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
//確定二分上下界
left = Math.min(left, matrix[i][j]);
right = Math.max(right, matrix[i][j]);
}
}
left -= 1;
right += 1;
while(left + 1 < right) {
//判定mid是不是第k小
int mid = left + (right - left) / 2;
long num = calc(mid, matrix);
//如果比mid小的超過k個,就可以縮小上界,否則提高下界
if(n * m - num >= (long)k) {
right = mid;
} else {
left = mid;
}
}
return right;
}
}
更多題解參考:九章官網solution
相關推薦
[leetcode/lintcode 題解] Amazon 面試題:排序矩陣中的從小到大第k個數
在一個排序矩陣中找從小到大的第 k 個整數。 排序矩陣的定義為:每一行遞增,每一列也遞增。
[leetcode/lintcode 題解] Amazon面試題:安排課程
你需要去上n門九章的課才能獲得offer,這些課被標號為 0 到 n-1 。 有一些課程需要“前置課程”,比如如果你要上課程0,你需要先學課程1,我們用一個匹配來表示他們: [0,1]
[leetcode/lintcode 題解] 微軟面試題:公平索引
現在給你兩個長度均為N的整數陣列 A 和 B。 當(A[0]+...A[K-1]),(A[K]+...+A[N-1]),(B[0]+...+B[K-1]) 和 (B[K]+...+B[N-1])四個和值大小相等時,稱索引K是一個公平索引。也就是說,索引K 可以使得A, B 兩個陣列被
[leetcode/lintcode 題解] Apple面試題:二叉樹的最大深度
給定一個二叉樹,找出其最大深度。 二叉樹的深度為根節點到最遠葉子節點的距離。
[leetcode/lintcode 題解] Facebook面試題:電話號碼的字母組合
給一個不包含0和1的數字字串,每個數字代表一個字母,請返回其所有可能的字母組合。
[leetcode/lintcode 題解] Google面試題:搜尋二維矩陣 II
寫出一個高效的演算法來搜尋m×n矩陣中的值,返回這個值出現的次數。 這個矩陣具有以下特性:
[leetcode/lintcode 題解] Google面試題:萬用字元匹配
判斷兩個可能包含萬用字元“?”和“*”的字串是否匹配。匹配規則如下: \'?\' 可以匹配任何單個字元。
[leetcode/lintcode 題解] LinkedIn面試題:房屋染色
這裡有n個房子在一列直線上,現在我們需要給房屋染色,分別有紅色藍色和綠色。每個房屋染不同的顏色費用也不同,你需要設計一種染色方案使得相鄰的房屋顏色不同,並且費用最小,返回最小的費用。
[leetcode/lintcode 題解] 微軟面試題:K個最近的點
給定一些 points 和一個 origin,從 points 中找到 k 個離 origin 最近的點。按照距離由小到大返回。如果兩個點有相同距離,則按照x值來排序;若x值也相同,就再按照y值排序。
[leetcode/lintcode 題解] Google面試題:資料流滑動視窗平均值
給出一串整數流和視窗大小,計算滑動視窗中所有整數的平均值。 線上評測地址:領釦題庫官網
[leetcode/lintcode 題解] Google面試題:字串解碼
給出一個表示式 s,此表示式包括數字,字母以及方括號。在方括號前的數字表示方括號內容的重複次數(括號內的內容可以是字串或另一個表示式),請將這個表示式展開成一個字串。
[leetcode/lintcode 題解] Facebook 面試題:和大於S的最小子陣列
給定一個由 n 個正整陣列成的陣列和一個正整數 s ,請找出該陣列中滿足其和 ≥ s 的最小長度子陣列。如果無解,則返回 -1。
[leetcode/lintcode 題解] Google 面試題:包裹黑色畫素點的最小矩形
一個由二進位制矩陣表示的圖,0 表示白色畫素點,1 表示黑色畫素點。黑色畫素點是聯通的,即只有一塊黑色區域。畫素是水平和豎直連線的,給一個黑色畫素點的座標 (x, y) ,返回囊括所有黑色畫素點的矩陣
[leetcode/lintcode 題解] Google 面試題:用棧實現佇列
正如標題所述,你需要使用兩個棧來實現佇列的一些操作。 佇列應支援push(element),pop() 和 top(),其中pop是彈出佇列中的第一個(最前面的)元素。
[leetcode/lintcode 題解] Google 面試題:最接近零的子陣列和
給定一個整數陣列,找到一個和最接近於零的子陣列。返回第一個和最右一個指數。你的程式碼應該返回滿足要求的子陣列的起始位置和結束位置。
【LeetCode/LintCode】Facebook面試題:子集 II
給定一個可能具有重複數字的列表,返回其所有可能的子集。 線上評測地址:
滴滴2020年面試題:如何找出最小的N個數?
【題目】 “學生表”裡記錄了學生的學號、入學時間等資訊。“成績表”裡是學生選課成績的資訊。兩個表中的學號一一對應。(滴滴2020年面試題)
《劍指Offer》面試題54. 二叉搜尋樹的第 k 大節點
技術標籤:t2:劍指Offer劍指Offer二叉搜尋樹的第k大節點 面試題54. 二叉搜尋樹的第 k 大節點
【LeetCode/LintCode】 題解丨Google高頻面試題:在排序陣列中找最接近的K個數
給一個目標數 target, 一個非負整數 k, 一個按照升序排列的陣列 A。在A中找與target最接近的k個整數。返回這k個數並按照與target的接近程度從小到大排序,如果接近程度相當,那麼小
[leetcode/lintcode 題解] 位元組跳動面試題:合併k個排序陣列
將 k 個有序數組合併為一個大的有序陣列。 線上評測地址:領釦題庫官網 樣例 1: