Leetcode【86溪厘、92胡本、148、206】

問題描述:【Linked List】86. Partition List
解題思路:

這道題是給一個(gè)鏈表和整數(shù) x畸悬,將小于 x 的數(shù)按位置順序放在鏈表左側(cè)侧甫,大于等于 x 的按位置順序放在右側(cè)。

類似于快排的劃分過程有木有蹋宦∨冢可以建立兩個(gè)指針 l_end 和 r_end,分別指向 x 的左右兩部分的尾部冷冗。再建立一個(gè)指針指向當(dāng)前結(jié)點(diǎn) cur僻爽,便于鏈表的遍歷。因?yàn)槲覀儾恢赖谝粋€(gè)結(jié)點(diǎn)和 x 的關(guān)系贾惦,所以可以建一個(gè)空結(jié)點(diǎn) node 指向 head胸梆,最后 head.next 就是答案。

  • l_end 初始化為 head(空結(jié)點(diǎn))须板,r_end 初始化為 None碰镜,cur 指向 head.next 第一個(gè)結(jié)點(diǎn);
  • 遍歷 cur:
    1习瑰、如果 cur.val < x and r_end == None绪颖,說明剛開始碰到的都是小于 x 的,就只需要移動 l_end 到 cur 的位置即可甜奄;
    2柠横、 如果 cur.val < x,這個(gè)時(shí)候 r_end 不為空课兄,利用這三個(gè)指針進(jìn)行交換和移動即可牍氛;
    3、否則烟阐,碰到的都是大于等于 x 的搬俊,就只需要移動 r_end 到 cur 的位置即可紊扬。

時(shí)間復(fù)雜度為 O(n),空間復(fù)雜度為 O(1)唉擂。

Python3 實(shí)現(xiàn):
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        node = ListNode(-1)  # 頭結(jié)點(diǎn)
        node.next = head
        head = node
        l_end, r_end, cur = head, None, head.next
        while cur:
            if cur.val < x and r_end == None:  # 沒遇到比 x 大的餐屎,只移動 l_end
                l_end = cur
            elif cur.val < x:  # r_end 不為 None,利用三指針交換
                r_end.next = cur.next  # 交換
                cur.next = l_end.next
                l_end.next = cur
                l_end = cur  # 移動
                cur = r_end
            else:
                r_end = cur
            cur = cur.next
        return head.next

問題描述:【Linked List】92. Reverse Linked List II
解題思路:

這道題是給一個(gè)鏈表和區(qū)間 [m, n]玩祟,反轉(zhuǎn)區(qū)間內(nèi)的數(shù)字腹缩。

這道題和下面的 Leetcode 206 思路相同。對于一個(gè)區(qū)間的反轉(zhuǎn)空扎,需要用 notr 記錄不用反轉(zhuǎn)區(qū)間的最后一個(gè)位置藏鹊;用 start 記錄反轉(zhuǎn)區(qū)間的頭指針;為了反轉(zhuǎn)方便勺卢,再定義 pre 和 cur 分別為前一個(gè)指針和當(dāng)前指針伙判。遍歷 cur,找到反轉(zhuǎn)區(qū)間黑忱,進(jìn)行指針的交換和移動操作即可宴抚。

時(shí)間復(fù)雜度為 O(n),空間復(fù)雜度為 O(1)甫煞。

Python3 實(shí)現(xiàn):
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
        if not head:
            return head
        # notr: 不用反轉(zhuǎn)區(qū)間的最后一個(gè)位置
        # start: 反轉(zhuǎn)區(qū)間的頭指針
        # pre, cur:前一個(gè)指針和當(dāng)前指針
        notr, start, pre, cur = None, None, None, head
        i = 1
        while cur:
            if i <= m:
                if i == m:  # 初始化四個(gè)指針
                    notr = pre
                    start = cur
                pre = cur
                cur = cur.next
            elif m < i <= n:  # 在起始位置的下一個(gè)位置反轉(zhuǎn)菇曲,通過指針交換完成
                pre.next = cur.next # 交換
                cur.next = start
                start = cur
                if m == 1:  # 從頭開始
                    head = cur
                else:  # 從中間開始
                    notr.next = start
                cur = pre.next  # 移動
            else:
                break
            i += 1
        return head

問題描述:【Linked List】148. Sort List
解題思路:

這道題是給一個(gè)鏈表,對鏈表排序抚吠。要求時(shí)間復(fù)雜度 O(nlogn)常潮,空間復(fù)雜度 O(1)。

首先楷力,肯定能想到要么是使用快速排序喊式,要么是歸并排序。剛好上面的 Leetcode 86 為鏈表劃分萧朝,所以就借助其思想實(shí)現(xiàn)了快排岔留。但是最后一個(gè) case 超時(shí)了(嚶嚶嚶),代碼如下:

Python3 實(shí)現(xiàn):
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        if not head or not head.next:  # 遞歸出口
            return head
        pivot = head.val
        le, ri, cur = head, None, head.next  # 左右區(qū)間劃分
        while cur:
            if cur.val < pivot and ri == None:
                le = cur
            elif cur.val < pivot:
                ri.next = cur.next  # 交換
                cur.next = le.next
                le.next = cur
                le = cur  # 移動
                cur = ri
            else:
                ri = cur
            cur = cur.next
        ri = le.next  # 左右兩側(cè)排序
        le.next = None
        lp = self.sortList(head.next)
        rp = self.sortList(ri)
        if lp == None:   # 將基準(zhǔn) head.val 放到中間
            head.next = rp
            lp = head
        else:
            cur = lp
            while cur.next:
                cur = cur.next
            cur.next = head
            head.next = rp
        return lp  # 返回鏈表頭結(jié)點(diǎn)

看了題解检柬,有人使用歸并排序 mergeSort 通過了献联,同樣可以做到時(shí)間復(fù)雜度為 O(nlogn),空間復(fù)雜度為 O(1)何址。代碼如下(不是我寫的里逆,懶得再寫一次了):

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        if head is None:
            return None
        p, i = head, 0
        while p:
            i += 1
            p = p.next
        return self.mergeSort(head, i)[0]
            
    def mergeSort(self,head,k):
        if k == 1:
            next = head.next
            head.next = None
            return head, next
        left_head, next = self.mergeSort(head, k//2)
        right_head, next = self.mergeSort(next, k-(k//2))
        return self.merge(left_head, right_head), next

    def merge(self, h1, h2):
        dummy = ListNode(0)
        p = dummy
        while h1 and h2:
            if h1.val <= h2.val:
                p.next = h1
                p = p.next
                h1 = h1.next
            else:
                p.next = h2
                p = p.next
                h2 = h2.next
        if h1 is None and h2 is not None:
            p.next = h2
        elif h2 is None and h1 is not None:
            p.next = h1
        return dummy.next

問題描述:【Linked List】206. Reverse Linked List
解題思路:

這道題是給一個(gè)鏈表,將鏈表反轉(zhuǎn)用爪。

鏈表反轉(zhuǎn)只需要兩個(gè)相鄰指針 pre 和 cur 即可原押。對于 cur 遍歷,先交換(3 次操作)后移動指針到正確的位置项钮,時(shí)間復(fù)雜度為 O(n)班眯。

Python3 實(shí)現(xiàn):
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not head:
            return head
        pre, cur = head, head.next
        while cur:
            pre.next = cur.next  # 交換
            cur.next = head
            head = cur
            cur = pre.next  # 移動
        return head
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末希停,一起剝皮案震驚了整個(gè)濱河市烁巫,隨后出現(xiàn)的幾起案子署隘,更是在濱河造成了極大的恐慌,老刑警劉巖亚隙,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件磁餐,死亡現(xiàn)場離奇詭異,居然都是意外死亡阿弃,警方通過查閱死者的電腦和手機(jī)诊霹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渣淳,“玉大人脾还,你說我怎么就攤上這事∪肜ⅲ” “怎么了鄙漏?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長棺蛛。 經(jīng)常有香客問我怔蚌,道長,這世上最難降的妖魔是什么旁赊? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任桦踊,我火速辦了婚禮,結(jié)果婚禮上终畅,老公的妹妹穿的比我還像新娘籍胯。我一直安慰自己,他們只是感情好离福,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布杖狼。 她就那樣靜靜地躺著,像睡著了一般术徊。 火紅的嫁衣襯著肌膚如雪本刽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天赠涮,我揣著相機(jī)與錄音子寓,去河邊找鬼。 笑死笋除,一個(gè)胖子當(dāng)著我的面吹牛斜友,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垃它,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼鲜屏,長吁一口氣:“原來是場噩夢啊……” “哼烹看!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起洛史,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤惯殊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后也殖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體土思,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年忆嗜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了己儒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捆毫,死狀恐怖闪湾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绩卤,我是刑警寧澤途样,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站省艳,受9級特大地震影響娘纷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜跋炕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一赖晶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辐烂,春花似錦遏插、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至扣草,卻和暖如春了牛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辰妙。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工鹰祸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人密浑。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓蛙婴,卻偏偏與公主長得像尔破,于是被迫代替她去往敵國和親街图。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353