1、反轉鏈表
leetcode206. 反轉鏈表
反轉一個單鏈表。
示例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
進階:
你可以迭代或遞歸地反轉鏈表。你能否用兩種方法解決這道題?
首先認識鏈表這種結構:
class Listnode:
? ?def _init_(self,x):
? ? ? self.val=x
? ? ? self.next=None
思路:
保存為數組,反轉數組,新產生一個鏈表,注意返回的鏈表要指向反轉數組產生的鏈表
代碼如下:
class?Solution:
????def?reverseList(self,?head:?ListNode)?->?ListNode:
????????l=[]
????????while?head:
????????????l.append(head.val)
????????????head=head.next
????????l.reverse()
????????if?len(l)==0:
????????????return?None
????????result=ListNode(l[0])
????????result1=ListNode(l[0])
????????result1=result
????????k=len(l)
????????for?i?in?range(1,k):
????????????result.next=ListNode(l[i])
????????????result=result.next
????????return?result1
實現反轉以及上一個節點變成當前節點
(1)將節點指向關系改變
class?Solution:
????def?reverseList(self,?head:?ListNode)?->?ListNode:
????????pre=None
????????cur=head
????????while?cur:
????????????tmp=cur.next
????????????cur.next=pre
????????????pre=cur
????????????cur=tmp
????????return?pre
2、相交鏈表
leetcode160. 相交鏈表
編寫一個程序,找到兩個單鏈表相交的起始節點。
如下面的兩個鏈表:
在節點 c1 開始相交。
示例 1:
輸入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
輸出:Reference of the node with value = 8
輸入解釋:相交節點的值為 8 (注意,如果兩個鏈表相交則不能為 0)。從各自的表頭開始算起,鏈表 A 為 [4,1,8,4,5],鏈表 B 為 [5,0,1,8,4,5]。在 A 中,相交節點前有 2 個節點;在 B 中,相交節點前有 3 個節點。
思路:對齊兩個鏈表
代碼如下:
class?Solution:
????def?getIntersectionNode(self,?headA:?ListNode,?headB:?ListNode)?->?ListNode:
?????????h1=headA
?????????h2=headB
?????????while?h1?!=?h2:
????????????????if?h1:
????????????????????h1=h1.next
????????????????else:
????????????????????h1=headB
????????????????if?h2:
????????????????????h2=h2.next
????????????????else:
????????????????????h2=headA
?????????return?h1
3、合并兩個有序的鏈表
leetcode21. 合并兩個有序鏈表
將兩個升序鏈表合并為一個新的 升序 鏈表并返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。?
示例:
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
思路:判斷大小,然后將有序添加到一個新的鏈表中,注意返回結果是指向新鏈表的next
代碼如下:
class?Solution:
????def?mergeTwoLists(self,?l1:?ListNode,?l2:?ListNode)?->?ListNode:
????????node=ListNode()
????????res=node
????????while?l1?and?l2:
????????????if?l1.val<=l2.val:
????????????????node.next=l1
????????????????l1=l1.next
????????????????node=node.next
????????????else:
????????????????node.next=l2
????????????????l2=l2.next
????????????????node=node.next
????????if?l1:
????????????node.next=l1
????????if?l2:
????????????node.next=l2
????????return?res.next
4、回文鏈表
leetcode234. 回文鏈表
請判斷一個鏈表是否為回文鏈表。
示例 1:
輸入: 1->2
輸出: false
示例 2:
輸入: 1->2->2->1
輸出: true
進階:
你能否用?O(n) 時間復雜度和 O(1) 空間復雜度解決此題?
思路1:遍歷產生數組,看數組倒序后是否和愿數組相同,時間和空間復雜度都為O(n)?
代碼如下:
class?Solution:
????def?isPalindrome(self,?head:?ListNode)?->?bool:
????????vals?=?[]
????????cur=head
????????while?cur:
????????????vals.append(cur.val)
????????????cur=cur.next
????????return?vals==vals[::-1]
5、環形鏈表
leetcode141. 環形鏈表
給定一個鏈表,判斷鏈表中是否有環。
如果鏈表中有某個節點,可以通過連續跟蹤 next 指針再次到達,則鏈表中存在環。 為了表示給定鏈表中的環,我們使用整數 pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鏈表中沒有環。注意:pos 不作為參數進行傳遞,僅僅是為了標識鏈表的實際情況。
如果鏈表中存在環,則返回 true 。 否則,返回 false 。
進階:
你能用 O(1)(即,常量)內存解決此問題嗎?
示例 1:
輸入:head = [3,2,0,-4], pos = 1
輸出:true
解釋:鏈表中有一個環,其尾部連接到第二個節點。
示例?2:
輸入:head = [1,2], pos = 0
輸出:true
解釋:鏈表中有一個環,其尾部連接到第一個節點。
示例 3:
輸入:head = [1], pos = -1
輸出:false
解釋:鏈表中沒有環。
思路:把節點存在字典或者集合中,再次出現說明有環。
代碼如下:
class?Solution:
????def?hasCycle(self,?head:?ListNode)?->?bool:
????????seen?=?{}
????????while?head:
????????????if?head?in?seen:
????????????????return?True
????????????seen[head]=1
????????????head?=?head.next
????????return?False