今天開始抽空刷一些leetcode里數(shù)據(jù)結(jié)構(gòu)的題,在這里記錄下來(lái)。按難易程度開始刷吧。
第一次更新:2018.10.15
237、刪除鏈表中的節(jié)點(diǎn)
開始看題的時(shí)候有點(diǎn)懵,沒(méi)太懂題目意思,刪除鏈表中值為某個(gè)值的節(jié)點(diǎn),但題目沒(méi)有給定鏈表。后來(lái)想了一會(huì),直接用該鏈表的下一個(gè)節(jié)點(diǎn)覆蓋掉這個(gè)節(jié)點(diǎn)就可以了。
class Solution(object):
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
if node:
node.val = node.next.val
node.next = node.next.next
206、反轉(zhuǎn)鏈表
先用迭代實(shí)現(xiàn)
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return None
a, b, c = None, head, head.next
while c:
b.next = a
a, b, c = b, c, c.next
b.next = a
return b
再用遞歸
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return None
elif not head.next:
return head
new_head = self.reverseList(head.next)
head.next.next = head
head.next = None
return new_head
21、合并兩個(gè)有序鏈表
class Solution(object):
def mergeTwoLists(self, l1, l2):
head = ListNode(-1)
temp = head
while l1 and l2:
if l1.val <= l2.val:
temp.next = l1
l1 = l1.next
temp = temp.next
else:
temp.next = l2
l2 = l2.next
temp = temp.next
if l1:
temp.next = l1
if l2:
temp.next = l2
return head.next
class Solution(object):
def deleteDuplicates(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return None
else:
temp = head
cur = head.next
while cur:
if cur.val != temp.val:
temp.next = cur
temp = temp.next
cur = cur.next
temp.next = None
return head
203、移除鏈表元素
class Solution(object):
def removeElements(self, head, val):
"""
:type head: ListNode
:type val: int
:rtype: ListNode
"""
new_head = ListNode(val-1)
temp = new_head
cur = head
while cur:
if cur.val != val:
temp.next = cur
temp = temp.next
cur = cur.next
temp.next = None
return new_head.next
234、回文鏈表
第一次做的時(shí)候把值存在了列表里,然后判斷列表是不是回文列表。可以用雙指針找到中間的節(jié)點(diǎn),還要用到之前的反轉(zhuǎn)鏈表,代碼比較長(zhǎng),也是調(diào)試了幾次才AC。
class Solution(object):
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
def reverseList(head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return None
a, b, c = None, head, head.next
while c:
b.next = a
a, b, c = b, c, c.next
b.next = a
return b
if not head or not head.next:
return True
slow = head
fast = head
while fast.next:
if not fast.next.next:
break
else:
fast = fast.next.next
slow = slow.next
new_listnode = reverseList(slow.next)
p = new_listnode
q = head
while p:
if p.val != q.val:
return False
p = p.next
q = q.next
return True
第二次更新:2018.10.16
141、環(huán)形鏈表
使用快指針和慢指針就可以了
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if not head:
return False
slow = head
fast = head
while fast:
if fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
return True
else:
return False
else:
return False
160、相交鏈表
劍指offer里面也有這題
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
p1 = headA
p2 = headB
while p1 != p2:
p1 = p1.next if p1.next else headB
p2 = p2.next if p2.next else headA
return p1
109、有序鏈表轉(zhuǎn)換二叉搜索樹
今天在劍指offer里刷了一道二叉搜索樹轉(zhuǎn)雙向鏈表的,這道題反過(guò)來(lái)將鏈表轉(zhuǎn)二叉搜索樹。有序鏈表的順序就是二叉搜索樹的中序遍歷的順序。
只要找到中間的節(jié)點(diǎn),然后遞歸就可以了。但是鏈表找中間節(jié)點(diǎn)有點(diǎn)麻煩,可以用笨辦法先轉(zhuǎn)為列表再找中間節(jié)點(diǎn),然后重新轉(zhuǎn)化為節(jié)點(diǎn)。但用雙指針也可以找到中間節(jié)點(diǎn),不過(guò)在遞歸過(guò)程中不斷找中間節(jié)點(diǎn)有點(diǎn)困難,沒(méi)有寫出來(lái)。還是參考了別人的代碼
class Solution(object):
def sortedListToBST(self, head):
"""
:type head: ListNode
:rtype: TreeNode
"""
def convert(head, tail):
if head == tail:
return None
if head.next == tail:
return TreeNode(head.val)
fast = head
mid = head
while fast != tail and fast.next != tail:
fast = fast.next.next
mid = mid.next
root = TreeNode(mid.val)
root.left = convert(head, mid)
root.right = convert(mid.next, tail)
return root
return convert(head, None)
24、兩兩交換鏈表中的節(jié)點(diǎn)
直接用遞歸
class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return None
if not head.next:
return head
a, b = head, head.next
temp = self.swapPairs(b.next)
b.next = a
a.next = temp
return b
114、二叉樹轉(zhuǎn)為鏈表
要求原地修改二叉樹,所以不能先序遍歷再連接。
class Solution(object):
def flatten(self, root):
if not root:
return None
if root.left:
self.flatten(root.left)
if root.right:
self.flatten(root.right)
temp = root.right
root.right = root.left
root.left = None
while root.right:
root = root.right
root.right = temp
148、排序鏈表
題目要求了時(shí)間復(fù)雜度:O(n log n)。好像快排,歸并排序,堆排序都是O(n log n)級(jí)別的,但我還沒(méi)看,先跳過(guò)
382、鏈表隨機(jī)節(jié)點(diǎn)
獲得長(zhǎng)度后用random模塊隨機(jī)一個(gè)數(shù)字代表第幾個(gè)節(jié)點(diǎn)
class Solution(object):
def __init__(self, head):
"""
@param head The linked list's head.
Note that the head is guaranteed to be not null, so it contains at least one node.
:type head: ListNode
"""
import random
self.head = head
def getRandom(self):
"""
Returns a random node's value.
:rtype: int
"""
if not self.head:
return None
length = 0
cur = self.head
while cur:
length += 1
cur = cur.next
index = random.randint(0, length-1)
cur = self.head
for i in range(length):
if i == index:
return cur.val
else:
cur = cur.next
i += 1
147、對(duì)鏈表進(jìn)行插入排序
劍指offer刷完我就去看排序!先跳過(guò)
328、奇偶鏈表
用了三個(gè)指針。
class Solution(object):
def oddEvenList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
a, b, c = head, head.next, head.next.next
new_head = b
i = 0
while c:
i += 1
a.next = c
a, b, c = b, c, c.next
if i%2 == 0:
a.next = new_head
else:
b.next = new_head
a.next = None
return head
第三次更新:2018.10.17
明天要開組會(huì),準(zhǔn)備了一晚上組會(huì)的東西= =,抓緊時(shí)間寫兩道題
143、重排鏈表
寫了很久,想法是后半段鏈表先翻轉(zhuǎn),然后前半段和后半段交叉連接就可以了。
class Solution(object):
def reorderList(self, head):
def reverse(head):
if not head:
return None
a, b, c = None, head, head.next
while c:
b.next = a
a, b, c = b, c, c.next
b.next = a
return b
if head and head.next:
fast = head
slow = head
while fast.next:
if fast.next.next:
fast = fast.next.next
slow = slow.next
else:
break
new_head = reverse(slow.next)
a = head
b = new_head
final_head = ListNode(0)
temp = final_head
i = 0
while b:
if i%2==0:
temp.next = a
temp = temp.next
a = a.next
if i%2 == 1:
temp.next = b
temp = temp.next
b = b.next
i += 1
temp.next = a
if temp.next:
temp.next.next = None
head = temp.next
2、兩數(shù)相加
最簡(jiǎn)單的可以直接將數(shù)值取出來(lái)再相加。當(dāng)然有更好的解法,參考了別人的,用memory記錄進(jìn)位
class Solution(object):
def addTwoNumbers(self, l1, l2):
mem = 0
new_head = ListNode(0)
cur = new_head
while l1 or l2:
a = l1.val if l1 else 0
b = l2.val if l2 else 0
c = a + b
if l1:
l1 = l1.next
if l2:
l2 = l2.next
cur.next = ListNode((c+mem)%10)
cur = cur.next
mem = (c+mem) // 10
if mem != 0:
cur.next = ListNode(mem)
return new_head.next
445、兩數(shù)相加Ⅱ
這題跟上一題類似,不過(guò)上一題最高位處于鏈表的尾節(jié)點(diǎn),這題最高位處于頭節(jié)點(diǎn)。簡(jiǎn)單一點(diǎn)的可以將兩個(gè)鏈表反轉(zhuǎn)后再?gòu)?fù)制上一題的代碼,但應(yīng)該有更好的答案,但我沒(méi)想出來(lái)。網(wǎng)上搜了一下其實(shí)就是把值都取出來(lái)存在棧里==。看來(lái)是我想復(fù)雜了
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
stack1 = []
stack2 = []
while l1:
stack1.append(l1.val)
l1 = l1.next
while l2:
stack2.append(l2.val)
l2 = l2.next
answer = None
carry = 0
while stack1 and stack2:
add = stack1.pop() + stack2.pop() + carry
carry = 1 if add >= 10 else 0
temp = answer
answer = ListNode(add % 10)
answer.next = temp
l = stack1 if stack1 else stack2
while l:
add = l.pop() + carry
carry = 1 if add >= 10 else 0
temp = answer
answer = ListNode(add % 10)
answer.next = temp
if carry:
temp = answer
answer = ListNode(1)
answer.next = temp
return answer
86、分隔鏈表
用了個(gè)比較笨的辦法,用一個(gè)新鏈表存儲(chǔ)小于目標(biāo)值的節(jié)點(diǎn),另一個(gè)新鏈表存儲(chǔ)其它節(jié)點(diǎn),最后再合并
class Solution(object):
def partition(self, head, x):
"""
:type head: ListNode
:type x: int
:rtype: ListNode
"""
smallhead = ListNode(-1)
bighead = ListNode(-1)
a , b= smallhead, bighead
cur = head
while cur:
if cur.val < x:
a.next = cur
a = a.next
cur = cur.next
else :
b.next = cur
b = b.next
cur = cur.next
a.next = None
b.next = None
cur = smallhead
while cur.next:
cur = cur.next
cur.next = bighead.next
return smallhead.next
92、反轉(zhuǎn)鏈表Ⅱ
跟反轉(zhuǎn)鏈表第一題差不多,注意一下反轉(zhuǎn)的界限就可以了。實(shí)際寫的時(shí)候出了很多問(wèn)題,最終還是沒(méi)寫出來(lái)。。參考別人代碼,實(shí)際思路是一樣的
class Solution:
def reverseBetween(self, head, m, n):
"""
:type head: ListNode
:type m: int
:type n: int
:rtype: ListNode
"""
if head == None or head.next == None or m >= n or m < 0 or n < 0:
return head
h = ListNode(-1)
h.next = head
pre = h
cur = head
i = 1
while i < m and cur != None:
pre = cur
cur = cur.next
i += 1
t1 = pre
t2 = cur
while i <= n and cur != None:
lat = cur.next
cur.next = pre
pre = cur
cur = lat
i += 1
t1.next = pre
t2.next = cur
return h.next
2018.10.20
class Solution:
# @param head, a ListNode
# @return a ListNode
def deleteDuplicates(self, head):
if not head:
return None
new_head = ListNode(head.val - 1)
temp = new_head
a, b, c = temp, head, head.next
while b:
if not c:
if b.val != a.val:
temp.next = b
break
else:
temp.next = None
break
elif a.val != b.val != c.val:
temp.next = b
temp = b
a, b, c = b, c, c.next
else:
a, b, c = b, c, c.next
b.next = None
return new_head.next
61、旋轉(zhuǎn)鏈表
調(diào)試了很久才AC。
class Solution(object):
def rotateRight(self, head, k):
if not head:
return None
if k == 0:
return head
length = 0
cur = head
while cur:
length += 1
cur = cur.next
if length == 1 or k%length==0:
return head
pos = length - k % length + 1
cur = head
i = 1
while i < pos-1:
cur = cur.next
i += 1
temp = cur
new_head = cur.next
cur = cur.next
while cur.next:
cur = cur.next
temp.next = None
cur.next = head
return new_head
19、刪除鏈表的倒數(shù)第N個(gè)節(jié)點(diǎn)
遍歷兩遍鏈表的話很容易,但一遍的話沒(méi)想到該怎么做。參考別人的答案:https://blog.csdn.net/dongrongyu/article/details/78346583
想法是這樣的:維護(hù)兩個(gè)指針,pre和end。一開始初始化時(shí)使得pre指針指向鏈表頭節(jié)點(diǎn),end指針指向pre+n的節(jié)點(diǎn)位置。然后同時(shí)往后移動(dòng)pre和end指針位置,使得end指針指向最后一個(gè)節(jié)點(diǎn),那么pre指針指向的則是end-n的節(jié)點(diǎn)位置(即倒數(shù)第n個(gè)元素的前一個(gè)節(jié)點(diǎn)),則將其刪除。
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
if not head:
return None
fast = head
for i in range(n):
fast = fast.next
if not fast:
return head.next
slow = head
while fast.next:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return head
142、環(huán)形鏈表Ⅱ
劍指offer里刷過(guò)了
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return None
fast = head
slow = head
while fast.next:
if not fast.next.next:
return None
else:
fast = fast.next.next
slow = slow.next
if fast == slow:
if fast==head:
return head
slow = head
while True:
fast = fast.next
slow = slow.next
if fast == slow:
return fast
return None