逐漸成爲靈魂畫手[doge]。。
複習鏈表:
鏈表中倒數第k個節點
class Solution:
def FindKthToTail(self, head, k):
# write code here, 快慢指針,k是兩個指針的相對固定舉例,當快指針到達None,慢指針就是結果
first = head
second = head
# 讓快指針先走k步
for i in range(k):
if first == None: # 注意這裏需要先判斷哦
return None
first = first.next
# 當快指針到達None的時候,慢指針就是倒數第K個節點
while first:
first = first.next
second = second.next
return second
反轉鏈表:
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
# 需要3個指針,分別指向比如第左號節點,讓它的指針指向None,
# while 當最右邊指針指向None的時候,這時的mid節點就是新的表頭節點
# 讓剛纔的中號節點指針指向左號
# 向右同時移動一步,3個指針,左號變爲中,中變爲右號,右號指向下一個節點
# 注意邊界
if pHead == None:
return None
if pHead.next == None:
return pHead
leftPointer = pHead
midPointer = leftPointer.next
rightPointer = midPointer.next
leftPointer.next = None
while rightPointer != None:
midPointer.next = leftPointer
leftPointer = midPointer
midPointer = rightPointer
rightPointer = rightPointer.next
midPointer.next = leftPointer # 邊界,當只有2個節點時,不走上面的while
return midPointer
合併兩個排序鏈表
需要 4個指針
class Solution:
# 返回合併後列表
def Merge(self, pHead1, pHead2):
# write code here
if pHead1 == None:
return pHead2
if pHead2 == None:
return pHead1
# 指針1
newHead = pHead1 if pHead1.val < pHead2.val else pHead2
# 指針2 & 3
tmp1 = pHead1
tmp2 = pHead2
if newHead == tmp1:
tmp1 = tmp1.next
else:
tmp2 = tmp2.next
# 指針4
pre = newHead
# 判斷條件,當不管誰,最後一個爲None的時候,退出循環
while tmp1 and tmp2:
if tmp1.val < tmp2.val:
pre.next = tmp1
pre = tmp1
tmp1 = tmp1.next
else:
pre.next = tmp2
pre = tmp2
tmp2 = tmp2.next
# 剩下最後一個節點情況,誰先到頭了,把pre鏈接到另一個剩下的節點
if tmp1 == None:
pre.next = tmp2
else:
pre.next = tmp1
return newHead
兩個鏈表的第一個公共節點
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
# 先找到2個鏈表的長度差
# 然後讓長的鏈表先走長度差
# 然後兩個指針同時走,當遇到相同的節點時候,那就是公共節點(注意邊界條件,兩個相同長度的鏈表)
tmp1 = pHead1
tmp2 = pHead2
while tmp1 and tmp2:
if tmp1 == tmp2:
return tmp1
tmp1 = tmp1.next
tmp2 = tmp2.next
if tmp1: # 意味着tmp2先到頭,等於None
return self.find_common(tmp1,tmp2,pHead1, pHead2)
if tmp2:
return self.find_common(tmp2,tmp1,pHead2, pHead1)
def find_common(self, long_pointer, short_pointer, long_head, short_head):
# 需要4個指針,2個指向兩個鏈表頭,2個分別指向鏈表節點
# 計算K的差距
k = 0
while long_pointer:
long_pointer = long_pointer.next
k += 1
# 先走k步
long_pointer = long_head
short_pointer = short_head
for i in range(k):
long_pointer = long_pointer.next
# 一起走直到相等
while long_pointer != short_pointer:
long_pointer = long_pointer.next
short_pointer = short_pointer.next
return long_pointer
鏈表中環的入口節點
核心: -> 判斷是否有環(快慢指針) -> 從相遇點走單步 --> over
# 利用快慢指針判斷是否存在環,快指針走2步,慢指針走1步
# 上一個while退出條件存在2個,當爲快指針走到None,或者 快慢指針相遇都會退出,這裏是只相遇
# 所以從相遇點,快指回到pHead, 慢指針繼續走那m,第一次遇到相同的節點就是環的起點
# 囉嗦的寫法
class Solution:
def EntryNodeOfLoop(self, pHead):
# 運行超時了!!!該方法不行
# write code here
if pHead == None:
return None
# 利用快慢指針判斷是否存在環,快指針走2步,慢指針走1步
fastPointer = pHead
slowPointer = pHead
while fastPointer and fastPointer.next:
fastPointer = fastPointer.next.next
slowPointer = slowPointer.next
if fastPointer == slowPointer:
break
# 上一個while退出條件存在2個,當爲快指針走到None,或者 快慢指針相遇都會退出
if fastPointer == None or fastPointer.next == None:
return None
# 到這裏就說明是快慢指針相遇了,需要按公式進行計算,搜索環入口節點
# 快慢指針相遇 所以慢指針走了l,快指針走了2l
# 慢指針環外面距離爲s,環裏走的長度爲d,環內沒走的長度爲m --> l = s + d ,
# 快指針走的距離爲 n*(m + d) + d + s = 2l
# 代入公式,所以 s = m + (n-1)(m+d) ,
# 所以從相遇點,快指回到pHead, 慢指針繼續走那m,第一次遇到相同的節點就是環的起點
fastPointer = pHead
while fastPointer != slowPointer:
fastPointer = fastPointer.next
slowPointer = slowPointer.next
return slowPointer
# 簡潔的寫法:
class Solution:
def EntryNodeOfLoop(self, pHead):
if pHead == None or pHead.next == None:
return None
fast = pHead
slow = pHead
while fast.next and slow:
fast = fast.next.next
slow = slow.next
if fast == slow:
fast = pHead
while fast != slow:
fast = fast.next
slow = slow.next
return fast
return None
刪除鏈表中的重複元素
class Solution:
def deleteDuplication(self, pHead):
# write code here
# 邊界條件
if pHead == None:
return None
# 需要3個指針,root,pre, cur,
root = ListNode(0) # 爲什麼需要root指針,因爲 1->1->2 最前面需要root指針
root.next = pHead
pre = root
cur = root
# 判斷單個連續 1->2->2->3
while cur:
while cur.next and cur.val == cur.next.val:
cur = cur.next
# 判斷多個連續情況 1->2->2->3->3->4
cur = cur.next
if cur and cur.next and cur.val == cur.next.val:
continue
pre.next = cur
pre = pre.next
return root.next
複雜鏈表的複製
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的head。
(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
# -*- coding:utf-8 -*-
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
self.clone_node(pHead)
self.clone_random(pHead)
return self.split(pHead)
def clone_node(self, pHead):
node = pHead
while node:
copynode = RandomListNode(node.label)
copynode.next = node.next
node.next = copynode
node = copynode.next
def clone_random(self, pHead):
node = pHead
while node:
clone = node.next
if node.random:
clone.random =node.random.next
node = clone.next
def split(self, pHead):
node = pHead
copyhead = copynode = None
if node:
copyhead = copynode = node.next
node.next = copynode.next
node = node.next
while node:
copynode.next, copynode = node.next, copynode.next
node.next, node = copynode.next, node.next
return copyhead