Follow the template in Powerful Ultimate Binary Search Template. Solved many problems

重點在於看出題目有 monotonicity,並寫出測試的 function(測試計算出的 mid 是否符合所需)。

Code

TLE 版本,中間的兩層 for loop 雖然有做 early stop,但是還是太久了。

class Solution {
public:
    int findKthNumber(int m, int n, int k) {
        int l = 1, r = m * n;
        while(l < r) {
            int mid = l + (r - l) / 2;
            int count = 0;
            for(int i = 1; i <= m; i++) {
                for(int j = 1; j <= n; j++) {
                    if(i * j <= mid) count++;
                    else break;
                }
            }
            if(count >= k) r = mid;
            else l = mid + 1;
        }
        return l;
    }
};

觀察矩陣,發現每一直行都是開頭的 element 的二的幾倍,因此可以用 mid 除上開頭元素,就知道在直行中有多少個元素比 mid 還要小。Time Complexity 及從 降低到

class Solution {
public:
    int findKthNumber(int m, int n, int k) {
        int l = 1, r = m * n;
        while(l < r) {
            int mid = l + (r - l) / 2;
            int count = 0;
            for(int i = 1; i <= m; i++) {
                int smallerInEachRow = min(mid / i, n);
                if(smallerInEachRow == 0) break;
                count += smallerInEachRow;
            }
            if(count >= k) r = mid;
            else l = mid + 1;
        }
        return l;
    }
};