Given an array with all elements sorted on each individual row and column find the K-th smallest one 有个做法是用heap, 但好像也不是很合适...
f*e
2 楼
复杂度要求呢?
【在 w****x 的大作中提到】 : Given an array with all elements sorted on each individual row and column : find the K-th smallest one : 有个做法是用heap, 但好像也不是很合适...
C*U
3 楼
你是说给定一个matrix 是么?
【在 w****x 的大作中提到】 : Given an array with all elements sorted on each individual row and column : find the K-th smallest one : 有个做法是用heap, 但好像也不是很合适...
l*c
4 楼
我怎么觉得用heap挺好的呢,worst case n^2, 但一般用不到那么多吧
c*r
5 楼
复杂度klogk, worst case是 n^2 log n, 跟直接sort是一样的
【在 l****c 的大作中提到】 : 我怎么觉得用heap挺好的呢,worst case n^2, 但一般用不到那么多吧
l*8
6 楼
我记得一个解法是从左下角出发, while (1) { if (target == element) { return found; } else if (target > element) { if (can move ritht) move right; else return notFound; } else { // target < element if (can move up) move up; else return notFound; }; 这个算法O(n+m) time, where n is row number and m is the column number. 你觉 得这个方法太慢了?
【在 w****x 的大作中提到】 : Given an array with all elements sorted on each individual row and column : find the K-th smallest one : 有个做法是用heap, 但好像也不是很合适...
Given: n by m matrix A, k 定义 int low[n]; // low[i]是在第i行查找的下限 int high[n]; // high[i]是在第i行查找的上限 low数组初始为全0, high全部是m. 取一个pivot (比如第n/2行的第k/n个元素), 在每行的low[i]和high[i]元素范围中找 该pivot对应的upper boundary,存为pos[i]. num = sum( pos[i] - low[i] | for all i) 就是比pivot小的element的数目。 if (num == k-1) { return pivot; } else if (num > k-1) { // 把high数组(查找上限)update为pos数组的值。 // 在新的low,high范围内递归查找k-th smallest element } else { // num < k-1 // 把low数组(查找下限)update为pos数组的值。 // 在新的low,high范围内递归查找(k-num)-th smallest element }
每轮更新low or high数组是O(n+m) time, 总共O(log(n*m))轮。 总的时间复杂度 O( (n+m)*log(n*m) ) 如果n==m, 就是O( 4* n* logn), 也就是O(n*logn)
【在 w****x 的大作中提到】 : Given an array with all elements sorted on each individual row and column : find the K-th smallest one : 有个做法是用heap, 但好像也不是很合适...
l*8
23 楼
关于boundary,可能还有bug。 但大概思路就是这样。
【在 l*********8 的大作中提到】 : Given: n by m matrix A, : k : 定义 : int low[n]; // low[i]是在第i行查找的下限 : int high[n]; // high[i]是在第i行查找的上限 : low数组初始为全0, high全部是m. : 取一个pivot (比如第n/2行的第k/n个元素), 在每行的low[i]和high[i]元素范围中找 : 该pivot对应的upper boundary,存为pos[i]. : num = sum( pos[i] - low[i] | for all i) 就是比pivot小的element的数目。 : if (num == k-1) {
d*s
24 楼
是这样的矩阵么? 1 3 5 2 7 8 6 9 11 如果是的话,可以按照/分层,每层都比上一层大,比如第一层是1,第二层是2,3,第三 层6 7 5等等 对于NxN矩阵中第k个最小的数字,所处的层数n由max n for k-n*(n+1)/2>0得到,然后 对该层(n+1)所有数字排序,复杂度nlog(n),取第int(k-n*(n+1)/2)个,得到结果
【在 l*********8 的大作中提到】 : Given: n by m matrix A, : k : 定义 : int low[n]; // low[i]是在第i行查找的下限 : int high[n]; // high[i]是在第i行查找的上限 : low数组初始为全0, high全部是m. : 取一个pivot (比如第n/2行的第k/n个元素), 在每行的low[i]和high[i]元素范围中找 : 该pivot对应的upper boundary,存为pos[i]. : num = sum( pos[i] - low[i] | for all i) 就是比pivot小的element的数目。 : if (num == k-1) {
f*e
44 楼
想到了一个Nlog(N)^2的算法。
【在 w****x 的大作中提到】 : Given an array with all elements sorted on each individual row and column : find the K-th smallest one : 有个做法是用heap, 但好像也不是很合适...
f*e
45 楼
每轮更新是nlog(m)吧?
【在 l*********8 的大作中提到】 : Given: n by m matrix A, : k : 定义 : int low[n]; // low[i]是在第i行查找的下限 : int high[n]; // high[i]是在第i行查找的上限 : low数组初始为全0, high全部是m. : 取一个pivot (比如第n/2行的第k/n个元素), 在每行的low[i]和high[i]元素范围中找 : 该pivot对应的upper boundary,存为pos[i]. : num = sum( pos[i] - low[i] | for all i) 就是比pivot小的element的数目。 : if (num == k-1) {
f*e
46 楼
两年前的advanced algorithm的习题: 告诉大家正确答案吧,我已经figure out该怎么弄了,不知道考试有多难?nnd。 上面有位同学说用求meidan of median,有点像,但不一样。我是用O(N)(第一次建medi ans的minheap和maxheap,后来为O(log(n))因为只是插入和删除操作)找出median最大 的数组A1和median最小的数组An,然后remove A1的upper half和An的lower half相同 数目的元素(i.e. min(0.5*size(A1),0.5*size(An))。然后重新找最大和最小median, 这么着iterate, so on and so forth. 这样就可以找到所有数组的median。 然后怎么把找kth变成找median呢,方法如下: 如果k!=n/2 or k不是median,就pack几个非常小(比所有数小, if k < n/2 )或非常大 的数(if k > n/2) 平均放到n个数组上去,然后求所有新数组的median,就是求老数组 的kth_element鸟。 这样我们的问题就完美地解决了。
【在 f*****e 的大作中提到】 : 想到了一个Nlog(N)^2的算法。
f*e
47 楼
复杂度: 没有,每次pop minheap and maxheap and insert minheap and maxheap操作耗时log( n),每次operation,至少有一个数组的size要减半,如果每个数组的size都是n,把一 个数组削的只剩一个要log(n),然后有n个数组,所以nlogn。nlogn * logn = nlogn^2
medi 目的 常大 的k
【在 f*****e 的大作中提到】 : 两年前的advanced algorithm的习题: : 告诉大家正确答案吧,我已经figure out该怎么弄了,不知道考试有多难?nnd。 : 上面有位同学说用求meidan of median,有点像,但不一样。我是用O(N)(第一次建medi : ans的minheap和maxheap,后来为O(log(n))因为只是插入和删除操作)找出median最大 : 的数组A1和median最小的数组An,然后remove A1的upper half和An的lower half相同 : 数目的元素(i.e. min(0.5*size(A1),0.5*size(An))。然后重新找最大和最小median, : 这么着iterate, so on and so forth. 这样就可以找到所有数组的median。 : 然后怎么把找kth变成找median呢,方法如下: : 如果k!=n/2 or k不是median,就pack几个非常小(比所有数小, if k < n/2 )或非常大 : 的数(if k > n/2) 平均放到n个数组上去,然后求所有新数组的median,就是求老数组
b*e
48 楼
这个有问题。或者我没看仔细? 1) 找到 pos[i] worst case 要 O( m * n ) 2) 递归中有一步还是 find k'th smallest, 那么岂不是无法递归下去了?
【在 l*********8 的大作中提到】 : Given: n by m matrix A, : k : 定义 : int low[n]; // low[i]是在第i行查找的下限 : int high[n]; // high[i]是在第i行查找的上限 : low数组初始为全0, high全部是m. : 取一个pivot (比如第n/2行的第k/n个元素), 在每行的low[i]和high[i]元素范围中找 : 该pivot对应的upper boundary,存为pos[i]. : num = sum( pos[i] - low[i] | for all i) 就是比pivot小的element的数目。 : if (num == k-1) {
c*t
49 楼
比如说10*10里找第10个数,是不是要插80个最小整数,变成18*10 这样就是找median (the 90th of 180)?
medi 常大
【在 f*****e 的大作中提到】 : 两年前的advanced algorithm的习题: : 告诉大家正确答案吧,我已经figure out该怎么弄了,不知道考试有多难?nnd。 : 上面有位同学说用求meidan of median,有点像,但不一样。我是用O(N)(第一次建medi : ans的minheap和maxheap,后来为O(log(n))因为只是插入和删除操作)找出median最大 : 的数组A1和median最小的数组An,然后remove A1的upper half和An的lower half相同 : 数目的元素(i.e. min(0.5*size(A1),0.5*size(An))。然后重新找最大和最小median, : 这么着iterate, so on and so forth. 这样就可以找到所有数组的median。 : 然后怎么把找kth变成找median呢,方法如下: : 如果k!=n/2 or k不是median,就pack几个非常小(比所有数小, if k < n/2 )或非常大 : 的数(if k > n/2) 平均放到n个数组上去,然后求所有新数组的median,就是求老数组
f*e
50 楼
right!其实也不用真填入,只要知道位置就行了。也不知道还能不能进一步优化。
median
【在 c********t 的大作中提到】 : 比如说10*10里找第10个数,是不是要插80个最小整数,变成18*10 这样就是找median : (the 90th of 180)? : : medi : 常大
c*t
51 楼
不错,和那个link解法一样。当然有论文有O(n)解法,看不到。 这个题还真有在interview碰到的。如果要写codes,我觉得还是 n size heap的解法最 容易实现。
【在 f*****e 的大作中提到】 : right!其实也不用真填入,只要知道位置就行了。也不知道还能不能进一步优化。 : : median
【在 w****x 的大作中提到】 : Given an array with all elements sorted on each individual row and column : find the K-th smallest one : 有个做法是用heap, 但好像也不是很合适...
w*x
55 楼
那个因该不是最优解,但是想法蛮独特的,是csdn上一个人告诉我的,后来我实现了一 下,很久以前做的。 =============================================================== // Find the kth element in young table // young table is a two dimensional matrix with its rows and columns sorted // Solution // It's hard to find the kth element directly, but its easy to find how many elements are smaller than a given number. // So, use binary search to find a number which is bigger than k elements in the young table. Then, travel through // the table to the element which is "just" bigger than the given number. // return the number bigger than int GetOrder(int** pArr, int n, int m, int v); int FindKth(int** pArr, int n, int m, int k) { assert(pArr && m>0 && n>0 && k>0 && kint nBeg = pArr[0][0]; int nEnd = pArr[n-1][m-1]; int nK = 0; int nMid = 0;
int nPrev = -1; do { nMid = (nBeg + nEnd)/2; nK = GetOrder(pArr, m, n, nMid); if (nK == nPrev) break; nPrev = nK; if (nK < k) nBeg = nMid; else nEnd = nMid; } while(nK != k); int iCur = 0; int jCur = m-1; int nRet = 0; bool bFirst = true; while (iCur < n && jCur >= 0) { if (nMid > pArr[iCur][jCur]) { if (bFirst) { nRet = pArr[iCur][jCur]; bFirst = false; } else nRet = nRet > pArr[iCur][jCur] ? nRet : pArr[iCur][jCur]; iCur++; } else { jCur--; } } assert(!bFirst); return nRet; } int GetOrder(int** pArr, int m, int n, int v) { assert(pArr && m>0 && n>0); int iCur = 0; int jCur = m-1; int nBiggerThan = 0; while (iCur < n && jCur >= 0) { if (pArr[iCur][jCur] >= v) { nBiggerThan += n-iCur; jCur--; } else iCur++; } return m*n - nBiggerThan; }
【在 w****x 的大作中提到】 : : 那个因该不是最优解,但是想法蛮独特的,是csdn上一个人告诉我的,后来我实现了一 : 下,很久以前做的。 : =============================================================== : // Find the kth element in young table : // young table is a two dimensional matrix with its rows and columns sorted : // Solution : // It's hard to find the kth element directly, but its easy to find how many : elements are smaller than a given number. : // So, use binary search to find a number which is bigger than k elements in
l*8
57 楼
不错,很有意思的解法 不过, if (nK == nPrev) break; 有问题吧?
sorted many in
【在 w****x 的大作中提到】 : : 那个因该不是最优解,但是想法蛮独特的,是csdn上一个人告诉我的,后来我实现了一 : 下,很久以前做的。 : =============================================================== : // Find the kth element in young table : // young table is a two dimensional matrix with its rows and columns sorted : // Solution : // It's hard to find the kth element directly, but its easy to find how many : elements are smaller than a given number. : // So, use binary search to find a number which is bigger than k elements in