剑指offer刷题记录
2020/09/02
链表中倒数第k个结点
递归法:链表的后续遍历,并用self.k来记录倒数节点的位置,找到了就返回找到的节点,否则返回None
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def __init__(self):
self.k = 0
def FindKthToTail(self, head, k):
# write code here
self.k = k
def recursion(head):
if head == None:
return None
res = recursion(head.next)
if res != None:
return res
self.k = self.k - 1
if self.k == 0:
return head
return None
return recursion(head)
栈辅助法:利用栈出栈倒序的机制来找到倒数第k个链表节点(注意临界值和特殊情况)
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
# write code here
if k == 0:
return None
stack = []
while head:
stack.append(head)
head = head.next
index = 0
while stack and index < k-1:
stack.pop()
index += 1
return stack[-1] if len(stack) > 0 else None
反转链表
链表的后序遍历,递归反转
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
if not pHead:
return None
# newHead
if pHead.next == None:
return pHead
# newHead
newHead = self.ReverseList(pHead.next)
pHead.next.next = pHead
pHead.next = None
return newHead
迭代翻转
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# 处理特殊情况
if pHead == None:
return None
# 初始化第一个要被翻转的节点和其前驱
cur = pHead
pre = None
# 开始迭代翻转,并更新cur和pre
while cur:
# 先记录下下一个将要被翻转的node
nxt = cur.next
cur.next = pre
pre = cur
cur = nxt
return pre
合并两个排序的链表
迭代法(需要一个空节点来辅助)
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
# 新建一个空的head
head = ListNode(0)
p = head
p1 = pHead1
p2 = pHead2
while p1 and p2:
if p1.val > p2.val:
# 连接
p.next = p2
# 更新p
p = p2
# 移动p2
p2 = p2.next
else:
p.next = p1
p = p1
p1 = p1.next
# 将剩余的那边的后续节点接到p的后面
if p1 or p2:
if p1:
p.next = p1
else:
p.next = p2
return head.next
递归法
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
# 只要有一边节点为空了就终止递归, 返回结果
if not pHead2:
return pHead1
elif not pHead1:
return pHead2
if pHead1.val > pHead2.val:
pHead2.next = self.Merge(pHead1, pHead2.next)
return pHead2
else:
pHead1.next = self.Merge(pHead1.next, pHead2)
return pHead1
树的子结构
一开始我用的是求两个相同的数进行处理,发现不对,原因是子树
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def HasSubtree(self, pRoot1, pRoot2):
# 注意这个函数不能采用求相同树
def recur(A, B):
# B是空的话可以直接返回True (B是A的子树)
if not B: return True
if not A or A.val != B.val: return False
return recur(A.left, B.left) and recur(A.right, B.right)
return bool(pRoot1 and pRoot2) and (recur(pRoot1, pRoot2) or self.HasSubtree(pRoot1.left, pRoot2) or self.HasSubtree(pRoot1.right, pRoot2))