剑指Offer(Python)

014-链表中倒数第k个结点

用快慢指针:p2p1先走k-11k:间隔了k-1步,然后再一起走,当p2为最后一个时,p1就为倒数第k个数

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def FindKthToTail(self, head, k):
        if not head or k<=0: return None
        p1 = head
        p2 = head
         #设置两个指针,p2指针先走(k-1)步,然后再一起走
        while (k-1)>0:
            if (p2.next != None):
                p2 = p2.next
                k -= 1
            else:
                return None
        while (p2.next != None): # 等同while p2.next:
            p1 = p1.next
            p2 = p2.next
        return p1

 

 

015-反转链表(链表转化赋值

思路:变化node.next

假设翻转1->2->3->4->5,(54321)

重要:

  • 1.构建辅助节点head
  • 2.我们将pnext指向tpnext
  • 3.tpnext指向headnext
  • 4.headnext指向tp
class ListNode:
     def __init__(self, x):
            self.val = x
            self.next = None

class Solution:
    # 新链表的表头,不是head,是head.next
    def ReverseList(self, pHead):
        if not pHead:return None
        #构建辅助节点head
        head = ListNode(0)
        head.next = pHead
        p = pHead
        while p.next != None:
            #链表节点转化操作(重要)
            tp = p.next
            p.next = tp.next
            tp.next = head.next
            head.next = tp
        return head.next

 

016-合并有序链表

思路:

新开个链表,两节点值比较,按大小存储即可

注意:head 与 pHead

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def Merge(self, pHead1, pHead2):
        if (not pHead1) and (not pHead2):return None
        pHead = ListNode(0)
        head = pHead
        while pHead1 and pHead2:
            if pHead1.val > pHead2.val:
                pHead.next = pHead2
                pHead2 = pHead2.next
            else:
                pHead.next = pHead1
                pHead1 = pHead1.next
            #注意:pHead也得移动到下一个
            pHead = pHead.next
        #注意:接收剩下得pHead1的所有值,不需要一个个去判断了(链表)
        if pHead1:
            pHead.next = pHead1
        if pHead2:
            pHead.next = pHead2
        #注意:pHead已经移动了,所有是head.next
        return head.next

 

017-树的子结构:

 

class Solution:
def HasSubtree(self, pRoot1, pRoot2):
#(ps:我们约定空树不是任意一个树的子结构)
if not pRoot1 or not pRoot2:return None
flag = False
#找到 A中与B根节点 相同的节点,判断接下来后续点
if pRoot1.val == pRoot2.val:
flag = self.DoseTreeAhasTreeB(pRoot1,pRoot2)
#如果没找到,继续遍历左,右子树,查找与B根节点 相同的节点
if not flag: 
#if pRoot1.val != pRoot2.val:
flag = self.HasSubtree(pRoot1.left,pRoot2)
if not flag:
#if pRoot1.val != pRoot2.val:
flag = self.HasSubtree(pRoot1.right,pRoot2)
return flag

# 需要注意的地方是: 前两个if语句不可以颠倒顺序
def DoseTreeAhasTreeB(self,pRoot1,pRoot2):
#如果B中节点遍历完了,A没完,说明B是A的子树
if not pRoot2:
return True
#如果B没遍历完,A遍历完了:说明B不是A的子树
if not pRoot1:
return False
#(都没遍历完)如果当前节点相同,继续遍历左右节点
if pRoot1.val == pRoot2.val:
return self.DoseTreeAhasTreeB(pRoot1.left,pRoot2.left) and self.DoseTreeAhasTreeB(pRoot1.right,pRoot2.right)
else:
return False

 

018-二叉树的镜像:

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Mirror(self, root):
        if not root:return None
        #左右交换:
        node = root.left
        root.left = root.right
        root.right =node
        #对左右节点递归
        self.Mirror(root.left)
        self.Mirror(root.right)
        #返回根节点
        return root

019-顺时针打印矩阵:

class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        res = []
        startX,startY,endX,endY = 0,0,len(matrix[0])-1,len(matrix)-1
        while (startX <= endX and startY <= endY):
            #1:
            i1 = startX
            while(i1 <= endX):
                res.append(matrix[startY][i1])
                i1 += 1
            #2:
            if endY > startY:
                i2 = startY + 1
                while(i2 <= endY):
                    res.append(matrix[i2][endX])
                    i2 += 1
            #3:
            if (endY > startY and endX > startX):
                i3 = endX - 1
                while(i3 >= startX):
                    res.append(matrix[endY][i3])
                    i3 -= 1
            #4:
            if (endY > startY+1 and endX > startX):
                i4 = endY - 1
                while(i4 >= startY + 1):
                    res.append(matrix[i4][startX])
                    i4 -= 1
            startX += 1
            startY += 1
            endX -= 1
            endY -= 1
        return res

 

020-包含min函数的栈

class Solution:
    def __init__(self): 
        self.stack1 = [] 
        self.stack2 = [] #辅助栈

    def push(self, node): 
        min = self.min()
        if not self.stack2 or node < min:
            self.stack2.append(node)
        else:
            self.stack2.append(min)
        self.stack1.append(node)
    
    def pop(self):
        if self.stack2:
            self.stack2.pop(-1) 
            return self.stack1.pop(-1)
    
    def top(self): #返回栈顶元素
        if self.stack1:
            return self.stack1[-1]
        
    def min(self):
        if self.stack2:
            return self.stack2[-1]

 

021-栈的压入、弹出序列

 

class Solution:
    def IsPopOrder(self, pushV, popV):
        stack=[] #辅助栈
        while popV:
            #  pushV,stack存在的情况下
            # 如果第一个元素相等,直接都弹出,根本不用压入stack
            if pushV and popV[0]==pushV[0]:
                popV.pop(0)
                pushV.pop(0)
            #如果stack的最后一个元素与popV中第一个元素相等,将两个元素都弹出
            elif stack and stack[-1]==popV[0]:
                stack.pop()
                popV.pop(0)
            # 如果pushV中有数据,压入stack
            elif pushV:
                stack.append(pushV.pop(0))
            # 上面情况都不满足,直接返回false。
            else:
                return False
        return True

 

022-从上往下打印二叉树

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    # 返回从上到下每个节点值列表,例:[1,2,3]
    def PrintFromTopToBottom(self, root):
        if not root: return []
        queue = []  
        res = [] #保存val
        queue.append(root) #队列存储二叉树根节点
        while queue:
            node = queue.pop(0)
            res.append(node.val)
            #从左到右:队列存储二叉树左右节点
            if node.left:    
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        return res

023-二叉搜索树(BST)的后序遍历序列:

 

class Solution:
    def VerifySquenceOfBST(self, sequence):
        if not sequence:return False
        #1.找到根节点:
        root = sequence[-1]
        #2.切分左右子树:找到右子树的第一个节点
        for i in range(len(sequence)):  #i的使用
            if sequence[i] > root:
                break
        #3.判断是否为右子树:每个值都大于根
        for j in range(i,len(sequence)):
            if sequence[j] < root:
                return False
        #4.递归左,右子树
        left = True
        if i> 0:
            left = self.VerifySquenceOfBST(sequence[0:i])
        right = True
        if i < len(sequence)-1:
            #不包括最后一个值(根节点)
            right = self.VerifySquenceOfBST(sequence[i:-1])
        return left and right

 

024-二叉树中和为某一值的路径

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def FindPath(self, root, expectNumber):
        def subFindPath(root):
            if root:
                path.append(root.val)
                #1.判断和是否相等,且该节点是否是叶节点
                if not root.right and not root.left and sum(path) == expectNumber:
                    res.append(path[:])
                #2.如果不是看它的左右节点
                else:
                    subFindPath(root.left),subFindPath(root.right)
                #!3.重点:回溯法
                path.pop()
        res, path = [], []
        subFindPath(root)
        return res

 

转载于:https://www.cnblogs.com/WuSehun/p/11061774.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值