2020-2-18 刷題總結(jié)「第 k 小問題」

0X00 leetcode 刷題

  • LeetCode 378. Kth Smallest Element in a Sorted Matrix
  • LeetCode 668. Kth Smallest Number in Multiplication Table
  • LeetCode 786. K-th Smallest Prime Fraction
  • LeetCode 719. Find K-th Smallest Pair Distance

0X01 基本模板總結(jié)

首先我們有這么一個基本問題

給定一個升序的數(shù)組:

[1, 5, 9, 10, 10, 20]

給定最小值 1 最大值 20 求 第 k 小的元素

hebing

對于第 kth 小的問題,有一種通用解法就是用 k size 的「最大堆」,這個以后再說,今天我們主要用二分查找

二分查找有一個模板:

lo, hi = min, max
while lo < hi:
    mid = lo + (hi - lo) // 2
    if check(xx):
        r = m
    else:
        l = m + 1
 return l

對于這個問題我們的解法如下:

class Solution:
    def kth(self, nums, minNumber, maxNumber, k):
        l, r = minNumber, maxNumber

        # 返回比 n 小于等于的個數(shù)
        def helper(start, end, nums, n):
            if start == end:
                return 1 if n > nums[start] else 0
            if end - start == 1:
                if n >= nums[end]: return 2
                if n >= nums[start]: return 1
                return 0
            if n > nums[end]:
                return end - start + 1
            mid = start + (end - start) // 2
            
            return helper(start, mid, nums, n) + helper(mid+1, end, nums, n)

            return start

        while l < r:
            m = l + (r - l) // 2
            if helper(m) >= k:
                r = m
            else:
                l = m + 1

        return l


a = [1, 4, 5, 5, 5, 5, 5, 5, 8]
s = Solution()
print(s.kth(a, 1, 8, 4))

對于這一種解法,一直有一個這么樣的疑問

為什么二分搜索出來的值,一定在數(shù)組里面..

  1. 一定存在第 k 小的值,而且是唯一的
  2. 一定是 r 先找到最后的答案
  3. r 找到答案后就不會改變了, 直到 l 與 r 合并

0X02 leetcode 做題

378. Kth Smallest Element in a Sorted Matrix

不是最優(yōu)解..但是就是按照上面的模板改的...

如果有重復(fù)元素的話,我就還是用遞歸吧.迭代太復(fù)雜了

class Solution:
    def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
        lo, hi = matrix[0][0], matrix[-1][-1]

        def helper(start, end, nums, n):
            if start == end:
                return 1 if n >= nums[start] else 0
            if end - start == 1:
                if n >= nums[end]: return 2
                if n >= nums[start]: return 1
                return 0
            if n >= nums[end]:
                return end - start + 1
            mid = start + (end - start) // 2
            return helper(start, mid, nums, n) + helper(mid+1, end, nums, n)


        while lo < hi:
            mid = lo + (hi - lo) // 2
            s = 0
            for row in matrix:
                s += helper(0, len(row) - 1, row, mid)
            if s  >= k:
                hi = mid
            else:
                lo = mid + 1
        
        return lo

668. Kth Smallest Number in Multiplication Table

class Solution:
    def findKthNumber(self, m: int, n: int, k: int) -> int: 
        
        # 返回有多少個 <= x 的數(shù)
        def helper(m, n, k, x):
            count = 0
            # 只需要把每一行的 x // i 加起來就行了
            # 如果 i 大于 x  x // i == 0 也就不需要繼續(xù)算下去了
            # 如果 m < x 那么剩下的也不用算了
            # 所以最大值是 min(x, m)
            for i in range(1, min(m+1, x+1)):
                # 一行長度可能不夠
                count += min(x // i, n)
                # 剪枝
                if count >= k: return count
            return count
        
        l, r = 1, m * n + 1

        while l < r:
            mid = l + (r - l) // 2
            if helper(m,n, k, mid) >= k:
                r = mid
            else:
                l = mid + 1

        return l

這道題用了模板題的結(jié)論,

在有重復(fù)的升序列數(shù)組中找到

下面兩道題待做

786. K-th Smallest Prime Fraction

719. Find K-th Smallest Pair Distance

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末窘拯,一起剝皮案震驚了整個濱河市琢歇,隨后出現(xiàn)的幾起案子迈窟,更是在濱河造成了極大的恐慌伤提,老刑警劉巖睛低,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诀浪,死亡現(xiàn)場離奇詭異终娃,居然都是意外死亡味廊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來余佛,“玉大人柠新,你說我怎么就攤上這事』匝玻” “怎么了恨憎?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長郊楣。 經(jīng)常有香客問我憔恳,道長,這世上最難降的妖魔是什么净蚤? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任钥组,我火速辦了婚禮,結(jié)果婚禮上今瀑,老公的妹妹穿的比我還像新娘程梦。我一直安慰自己,他們只是感情好橘荠,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布屿附。 她就那樣靜靜地躺著,像睡著了一般哥童。 火紅的嫁衣襯著肌膚如雪挺份。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天如蚜,我揣著相機(jī)與錄音压恒,去河邊找鬼。 笑死错邦,一個胖子當(dāng)著我的面吹牛探赫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播撬呢,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼伦吠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了魂拦?” 一聲冷哼從身側(cè)響起毛仪,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芯勘,沒想到半個月后箱靴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡荷愕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年衡怀,在試婚紗的時候發(fā)現(xiàn)自己被綠了棍矛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡抛杨,死狀恐怖够委,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情怖现,我是刑警寧澤茁帽,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站屈嗤,受9級特大地震影響潘拨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恢共,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一战秋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讨韭,春花似錦、人聲如沸癣蟋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疯搅。三九已至濒生,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幔欧,已是汗流浹背罪治。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留礁蔗,地道東北人觉义。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像浴井,于是被迫代替她去往敵國和親晒骇。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容