Leetcode【24案狠、109、328钱雷、445骂铁、725】

問題描述:【Linked List、Recursion】24. Swap Nodes in Pairs
解題思路:

這道題是給一個鏈表罩抗,相鄰結(jié)點數(shù)值兩兩進行交換拉庵,要求不修改結(jié)點值且只能操作鏈表本身。

方法1:三指針完成交換

鏈表中一般涉及兩個結(jié)點交換的操作套蒂,基本上需要相鄰的三個指針 pre1钞支,pre2茫蛹,cur 完成三次交換操作,然后再移動三個指針到下一個正確的位置烁挟。
因此婴洼,我們只需要循環(huán) cur 的位置,往后一直遍歷直到鏈表為空為止信夫。

在這道題中窃蹋,因為是兩兩交換,所以方便的解法就是建立一個空給點 node静稻,作為鏈表的頭結(jié)點 head警没,最后返回的 head.next 就是答案。

注意在交換的過程中振湾,每次交換的三個操作要保證鏈表不能斷杀迹。

時間復(fù)雜度 O(n),空間復(fù)雜度 O(1)押搪。

Python3 實現(xiàn):

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

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        if head == None or head.next == None: return head
        node = ListNode(-1)  # 頭部插入一個空結(jié)點
        node.next = head
        head = node
        # 三指針法
        pre2, pre1, cur = head, head.next, head.next.next
        while cur:
            pre2.next = cur  # 交換
            pre1.next = cur.next
            cur.next = pre1
            pre2 = pre1  # 修改
            pre1 = pre1.next
            if pre1 == None: break  # 防止pre1.next為空
            cur = pre1.next
        return head.next

方法2:遞歸

這道題實際上還可以使用遞歸(只不過不太好想树酪,看了別人的代碼才恍然大悟)。

1大州、函數(shù)的返回值:交換后的鏈表的頭結(jié)點 head续语。
2、遞歸函數(shù)做了什么:假設(shè) 1->2->3->4->5->...厦画,遞歸函數(shù)完成了 3->4->5... 的交換 swapPairs(head.next.next)疮茄,并返回了指向 4 的 head,因此需要建一個 second 指向 2根暑,然后將 head.next 指向遞歸函數(shù)的返回值力试,并將 second 作為頭結(jié)點 head,最后返回 second排嫌。
3畸裳、遞歸出口:如果鏈表為空或者 head.next 為空,就之間返回 head淳地。

總之怖糊,你不用去想遞歸函數(shù) swapPairs() 后面的交換是怎么完成的,只需要知道它能夠完成交換即可(或許這就是遞歸的精髓吧)颇象。

時間復(fù)雜度 O(n)蓬抄,空間復(fù)雜度 O(1)。

Python3 實現(xiàn):

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

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        if head == None or head.next == None:  # 遞歸出口
            return head
        second = head.next
        head.next = self.swapPairs(head.next.next)
        second.next = head
        return second

問題描述:【Linked List夯到、Tree】109. Convert Sorted List to Binary Search Tree
解題思路:

這道題是給一個有序鏈表嚷缭,將其轉(zhuǎn)化為高度平衡的二叉搜索樹。

要將有序鏈表轉(zhuǎn)化為高度平衡的二叉搜索樹,就需要從鏈表的中間斷開阅爽,然后對于左右鏈表就行遞歸調(diào)用即可路幸。具體細(xì)節(jié):

1、鏈表查找中間點可以通過快慢指針來操作付翁。
2简肴、找到中點后,要以中點的值建立一個樹的根結(jié)點百侧,再把原鏈表斷開砰识,分為前后兩個鏈表,都不能包含原中結(jié)點佣渴,然后再分別對這兩個鏈表遞歸調(diào)用原函數(shù)辫狼,分別連上左右子結(jié)點即可。

時間復(fù)雜度為 O(nlogn)辛润,空間復(fù)雜度為 O(1)膨处。

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

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def sortedListToBST(self, head: ListNode) -> TreeNode:
        if head == None:
            return None
        if head.next == None:
            return TreeNode(head.val)
        pre = None  # 記錄 slow 的前一個結(jié)點,便于斷開左右鏈表
        slow = fast = head
        while fast and fast.next:
            pre = slow
            slow = slow.next
            fast = fast.next.next
        pre.next = None # 從中間斷開
        node = TreeNode(slow.val)
        node.left = self.sortedListToBST(head) # [head, slow-1] 左區(qū)間
        node.right = self.sortedListToBST(slow.next)  # [slow+1,] 右區(qū)間
        return node

問題描述:【Linked List】328. Odd Even Linked List
解題思路:

這道題是給一個鏈表砂竖,將奇數(shù)位置的數(shù)按位置順序排在鏈表前面真椿,偶數(shù)位置的數(shù)按位置順序排在鏈表后面。要求空間復(fù)雜度 O(1)乎澄,時間復(fù)雜度 O(n)突硝。

設(shè)置三個指針,一個指向奇數(shù)尾部的指針 p置济,一個指向當(dāng)前結(jié)點 cur解恰,一個指向當(dāng)前結(jié)點的前一個結(jié)點 pre。遍歷 cur 的過程中交換三個指針的指向舟肉,然后再移動它們到下一個正確的位置即可。

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

class Solution:
    def oddEvenList(self, head: ListNode) -> ListNode:
        if head == None: return None
        p = pre = head   # p: 奇數(shù)尾結(jié)點, pre: cur的前一個結(jié)點
        cur = head.next  # 當(dāng)前結(jié)點
        while cur:
            pre = pre.next
            cur = cur.next
            if cur == None:  # 防止后面交換的時候cur沒有next域
                break
            pre.next = cur.next # 交換
            cur.next = p.next
            p.next = cur
            p = p.next  # 下一次交換做準(zhǔn)備
            cur = pre.next
        return head

問題描述:【Linked List】445. Add Two Numbers II
解題思路:

這道題是給兩個鏈表查库,將兩個鏈表相加路媚。

使用了一種簡單的做法,就是將兩個鏈表的值保存在 list 中翠语,然后反向遍歷 list唇跨,利用頭插法構(gòu)造新鏈表款咖,將每次計算的各個位的結(jié)果保存在新鏈表中即可。這樣時間復(fù)雜度和空間復(fù)雜度均為 O(n)裤园,代碼如下。

實際上這道題還可以使用鏈表反轉(zhuǎn)的思想剂府,將兩鏈表反轉(zhuǎn)拧揽,然后再求和。這樣空間復(fù)雜度可以做到 O(1)。

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

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        list1, list2 = [], []
        head1, head2 = l1, l2
        while head1:
            list1.append(head1.val)
            head1 = head1.next
        while head2:
            list2.append(head2.val)
            head2 = head2.next
        i, j, c = len(list1) - 1, len(list2) - 1, 0  # c:進位
        head = None
        while i >= 0 or j >= 0 or c == 1:
            add = c
            if i >= 0: add += list1[i]
            if j >= 0: add += list2[j]
            c = add // 10
            node = ListNode(add % 10)
            node.next = head  # 頭插法
            head = node
            i, j = i - 1, j - 1 
        return head

問題描述:【Linked List】725. Split Linked List in Parts
解題思路:

這道題是給一個鏈表和整數(shù) k淤袜,將鏈表劃分成長度盡可能相等的 k 個連續(xù)部分痒谴,返回鏈表列表。

首先需要注意铡羡,鏈表列表是指一個列表积蔚,列表中每一項是一個鏈表。這道題根據(jù)鏈表的長度 size (先遍歷一次鏈表)分為兩種情況:

1烦周、size <= k:每段鏈表只有一個值或者為 None尽爆。
2、size > k:通過 div, mod = divmod(size, k) 來計算每段鏈表中至少應(yīng)該包含 div 個值读慎,然后將 mod 平均分配到前面每一段鏈表中漱贱。

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

class Solution:
    def splitListToParts(self, root: ListNode, k: int) -> List[ListNode]:
        cur = root
        size = 0  # 鏈表長度
        while cur:
            size += 1
            cur = cur.next
        ans = []  # 結(jié)果
        if size <= k:
            cur = root
            for i in range(k):
                if i < size:
                    ans.append(ListNode(cur.val))
                    cur = cur.next
                else:
                    ans.append(None)  # 空鏈表
        else:
            div, mod = divmod(size, k)
            for _ in range(k):  # 對于每一段
                head = cur = root  # head 構(gòu)造每一段鏈表
                for _ in range(div - 1):  # 注意少循環(huán)一次,防止 cur.next 越界
                    cur = cur.next
                if mod > 0:  # 有余數(shù)贪壳,平均分配到前面每一段鏈表中
                    cur = cur.next
                    mod -= 1
                root = cur.next  # root 指向剩余的鏈表
                cur.next = None  # 截斷
                ans.append(head) # 將每一段鏈表保存
        return ans
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饱亿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子闰靴,更是在濱河造成了極大的恐慌彪笼,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚂且,死亡現(xiàn)場離奇詭異配猫,居然都是意外死亡,警方通過查閱死者的電腦和手機杏死,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門泵肄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人淑翼,你說我怎么就攤上這事腐巢。” “怎么了玄括?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵冯丙,是天一觀的道長。 經(jīng)常有香客問我遭京,道長胃惜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任哪雕,我火速辦了婚禮船殉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘斯嚎。我一直安慰自己利虫,他們只是感情好挨厚,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著列吼,像睡著了一般幽崩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寞钥,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天慌申,我揣著相機與錄音,去河邊找鬼理郑。 笑死蹄溉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的您炉。 我是一名探鬼主播柒爵,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼赚爵!你這毒婦竟也來了棉胀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤冀膝,失蹤者是張志新(化名)和其女友劉穎唁奢,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窝剖,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡麻掸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赐纱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脊奋。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖疙描,靈堂內(nèi)的尸體忽然破棺而出诚隙,到底是詐尸還是另有隱情,我是刑警寧澤起胰,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布久又,位于F島的核電站,受9級特大地震影響待错,放射性物質(zhì)發(fā)生泄漏籽孙。R本人自食惡果不足惜烈评,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一火俄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讲冠,春花似錦瓜客、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玻熙。三九已至,卻和暖如春疯攒,著一層夾襖步出監(jiān)牢的瞬間嗦随,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工敬尺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留枚尼,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓砂吞,卻偏偏與公主長得像署恍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蜻直,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

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