剑指offer代码上

#3.py

# jc3找出数组中重复的数字。
# 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
# 示例 1:
# 输入:
# [2, 3, 1, 0, 2, 5, 3]
# 输出:2 或 3  
# 限制:
# 2 <= n <= 100000
class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        c=Counter(nums)
        for k,v in c.items():
            if v>1:
                return k

#4.py

# 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
# 示例:

# 现有矩阵 matrix 如下:

# [
#   [1,   4,  7, 11, 15],
#   [2,   5,  8, 12, 19],
#   [3,   6,  9, 16, 22],
#   [10, 13, 14, 17, 24],
#   [18, 21, 23, 26, 30]
# ]
# 给定 target = 5,返回 true。
# 给定 target = 20,返回 false。

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        if len(matrix)==0:return False
        i=0
        j=len(matrix[0])-1
        while i<len(matrix) and j>=0:
            if matrix[i][j]<target:
                i+=1
            elif matrix[i][j]>target:
                j-=1
            else:
                return True
        return False

#5.py

# 请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
# 示例 1:

# 输入:s = "We are happy."
# 输出:"We%20are%20happy."


class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        if len(matrix)==0:return False
        i=0
        j=len(matrix[0])-1
        while i<len(matrix) and j>=0:
            if matrix[i][j]<target:
                i+=1
            elif matrix[i][j]>target:
                j-=1
            else:
                return True
        return False

#6.py

# 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
# 示例 1:
# 输入:head = [1,3,2]
# 输出:[2,3,1]
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reversePrint(self, head: ListNode) -> List[int]:
        # res=[]
        # while head:
        #     res.append(head.val)
        #     head=head.next
        # return res[::-1]
        #辅助栈
        res=[]
        stack=[]
        while head:
            stack.insert(0,head)
            head=head.next
        
        while stack:
            res.append(stack.pop(0).val)
        return res

#7.py

# 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
# 例如,给出

# 前序遍历 preorder = [3,9,20,15,7]
# 中序遍历 inorder = [9,3,15,20,7]
# 返回如下的二叉树:

#     3
#    / \
#   9  20
#     /  \
#    15   7

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if len(preorder)==0:return None
        rootval=preorder[0]
        index=inorder.index(rootval)
        left=inorder[:index]
        right=inorder[index+1:]
        t=TreeNode(-1)
        t.val=rootval
        t.left=self.buildTree(preorder[1:index+1],left)
        t.right=self.buildTree(preorder[index+1:],right)
        return t

#9.py

# 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
# 示例 1:

# 输入:
# ["CQueue","appendTail","deleteHead","deleteHead"]
# [[],[3],[],[]]
# 输出:[null,null,3,-1]
# 示例 2:

# 输入:
# ["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
# [[],[],[5],[2],[],[]]
# 输出:[null,-1,null,null,5,2]
class CQueue:

    def __init__(self):
        self.a=[]
        #b是辅助栈
        self.b=[]


    def appendTail(self, value: int) -> None:
        while self.a:
            self.b.insert(0,self.a.pop(0))
        self.a.insert(0,value)
        while len(self.b):
            self.a.insert(0,self.b.pop(0))
        #print(self.a)


    def deleteHead(self) -> int:
        #print(self.a)
        if not self.a:return -1
        return self.a.pop(0)

#10_1.py

# 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:

# F(0) = 0,   F(1) = 1
# F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
# 斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

# 答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

#  

# 示例 1:

# 输入:n = 2
# 输出:1
# 示例 2:

# 输入:n = 5
# 输出:5
class Solution:
    def fib(self, n: int) -> int:
        if n==0:return 0
        if n==1:return 1
        dp=[0]*(n+1)
        dp[0]=0
        dp[1]=1
        for i in range(2,n+1):
            dp[i]=dp[i-1]+dp[i-2]
        print(dp)
        return dp[-1]%(1000000007)  

#10_2.py

# 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
# 答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
# 示例 1:

# 输入:n = 2
# 输出:2
# 示例 2:

# 输入:n = 7
# 输出:21
# 示例 3:

# 输入:n = 0
# 输出:1
class Solution:
    def numWays(self, n: int) -> int:
        if n==0:return 1
        if n==1:return 1
        if n==2:return 2
        dp=[0]*(n)
        dp[0]=1
        dp[1]=2
        for i in range(2,n):
            dp[i]=dp[i-1]+dp[i-2]
        print(dp)
        return dp[-1]%(1000000007)

#11.py

# 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。  

# 示例 1:

# 输入:[3,4,5,1,2]
# 输出:1
# 示例 2:
# 输入:[2,2,2,0,1]
# 输出:0
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        left=0
        right=len(numbers)-1
        while left<right:
            mid=(left+right)//2
            if numbers[mid]>numbers[right]:
                left=mid+1
            elif numbers[mid]<numbers[right]:
                right=mid
            else:right-=1
        return numbers[left]

#12.py

# 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。

# [["a","b","c","e"],
# ["s","f","c","s"],
# ["a","d","e","e"]]

# 但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

#  

# 示例 1:

# 输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
# 输出:true
# 示例 2:

# 输入:board = [["a","b"],["c","d"]], word = "abcd"
# 输出:false
class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        dx=[0,-1,0,1]
        dy=[-1,0,1,0]
        def dfs(x,y,k):
            if word[k]!=board[x][y]:
                return False
            if k==len(word)-1:return True
            t=board[x][y]
            board[x][y]="*"
            for i in range(4):
                if 0<=x+dx[i]<=len(board)-1 and 0<=y+dy[i]<=len(board[0])-1:
                    if dfs(x+dx[i],y+dy[i],k+1):
                        return True
            board[x][y]=t

        for i in range(len(board)):
            for j in range(len(board[0])):
                print(i,j)
                if dfs(i,j,0):
                    return True
            
        return False

#13.py

# 地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

# 示例 1:
# 输入:m = 2, n = 3, k = 1
# 输出:3
# 示例 2:
# 输入:m = 3, n = 1, k = 0
# 输出:1
class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        def dfs(i, j, si, sj):
            if i>=m or j>=n or si+sj>k or (i,j) in visited:return 0
            visited.add((i,j))
            return 1+dfs(i+1,j,si+1 if (i+1)%10!=0 else si-8,sj)+dfs(i,j+1,si,sj+1 if (j+1)%10!=0 else sj-8)
        
        visited=set()
        return dfs(0,0,0,0)

#14_1.py

# 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]*k[1]*...*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

# 示例 1:

# 输入: 2
# 输出: 1
# 解释: 2 = 1 + 1, 1 × 1 = 1
# 示例 2:

# 输入: 10
# 输出: 36
# 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
class Solution:
    def cuttingRope(self, n: int) -> int:
        if n<=3:
            return n-1
        div=n//3
        remain=n%3
        if remain==0:
            return 3**div
        if remain==1:
            return 3**(div-1)*4
        if remain==2:
            return 2*3**div

#14_2.py

# 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m - 1] 。请问 k[0]*k[1]*...*k[m - 1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

# 答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

class Solution:
    def cuttingRope(self, n: int) -> int:
        if n<=3:
            return n-1
        div=n//3
        remain=n%3
        if remain==0:
            return 3**div%1000000007
        if remain==1:
            return 3**(div-1)*4%1000000007
        if remain==2:
            return 2*3**div%1000000007

#15.py

# 请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

# 示例 1:

# 输入:00000000000000000000000000001011
# 输出:3
# 解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
# 示例 2:

# 输入:00000000000000000000000010000000
# 输出:1
# 解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。
# 示例 3:

# 输入:11111111111111111111111111111101
# 输出:31
# 解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。

class Solution:
    def hammingWeight(self, n: int) -> int:
        mask=1
        count=0
        for i in range(32):
            if n&mask>0:
                count+=1
            mask=mask<<1
        return count

#16.py

# 实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
# 示例 1:

# 输入: 2.00000, 10
# 输出: 1024.00000
# 示例 2:

# 输入: 2.10000, 3
# 输出: 9.26100
# 示例 3:

# 输入: 2.00000, -2
# 输出: 0.25000
# 解释: 2-2 = 1/22 = 1/4 = 0.25
class Solution:
    def myPow(self, x: float, n: int) -> float:
        if n==0:return 1
        elif n<0: return 1.0/self.myPow(x,-n)
        elif n%2==0:return self.myPow(x*x,n//2)
        else:return self.myPow(x*x,n//2)*x

#17.py

# 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。

# 示例 1:

# 输入: n = 1
# 输出: [1,2,3,4,5,6,7,8,9]
class Solution:
    def printNumbers(self, n: int) -> List[int]:
        largest=9
        for i in range(1,n):
            largest=largest*10+9
        return [i for i in range(1,largest+1)]

#18.py

# 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

# 返回删除后的链表的头节点。

# 注意:此题对比原题有改动

# 示例 1:

# 输入: head = [4,5,1,9], val = 5
# 输出: [4,1,9]
# 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
# 示例 2:

# 输入: head = [4,5,1,9], val = 1
# 输出: [4,5,9]
# 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
class Solution:
    def deleteNode(self, head: ListNode, val: int) -> ListNode:
        dummy=ListNode(-1)
        dummy.next=head
        if head.val==val:return head.next
        while head and head.next:
            if head.next.val==val:
                head.next=head.next.next
            head=head.next
        return dummy.next

#19.py

#请实现一个函数用来匹配包含'. '和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"和"ab*a"均不匹配。
class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        slen=len(s)
        plen=len(p)
        dp=[[False]*(plen+1) for _ in  range(slen+1)]
        dp[0][0]=True
        for i in range(plen):
            if p[i]=="*":
                dp[0][i+1]=dp[0][i-1]
        
        for i in range(slen):
            for j in range(plen):
                if p[j]=="." or s[i]==p[j]:
                    dp[i+1][j+1]=dp[i][j]
                elif p[j]=="*":
                    if s[i]!=p[j-1]:
                        dp[i+1][j+1]=dp[i+1][j-1]
                    if p[j-1]=="." or s[i]==p[j-1]:
                        dp[i+1][j+1]=(dp[i][j+1] | dp[i+1][j] | dp[i+1][j-1])
                    
        print(dp)
        return dp[-1][-1]

#20.py

#请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"-1E-16"、"0123"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。
class Solution:
    def isNumber(self, s: str) -> bool:

        state = [
            {},
            # 状态1,初始状态(扫描通过的空格)
            {"blank": 1, "sign": 2, "digit": 3, ".": 4},
            # 状态2,发现符号位(后面跟数字或者小数点)
            {"digit": 3, ".": 4},
            # 状态3,数字(一直循环到非数字)
            {"digit": 3, ".": 5, "e": 6, "blank": 9},
            # 状态4,小数点(后面只有紧接数字)
            {"digit": 5},
            # 状态5,小数点之后(后面只能为数字,e,或者以空格结束)
            {"digit": 5, "e": 6, "blank": 9},
            # 状态6,发现e(后面只能符号位, 和数字)
            {"sign": 7, "digit": 8},
            # 状态7,e之后(只能为数字)
            {"digit": 8},
            # 状态8,e之后的数字后面(只能为数字或者以空格结束)
            {"digit": 8, "blank": 9},
            # 状态9, 终止状态 (如果发现非空,就失败)
            {"blank": 9}
        ]
        cur_state = 1
        for c in s:
            if c.isdigit():
                c = "digit"
            elif c in " ":
                c = "blank"
            elif c in "+-":
                c = "sign"

            if c not in state[cur_state]:
                return False
            cur_state=state[cur_state][c]

        if cur_state not in [3,5,8,9]:
            return False
        return True

#21.py

#输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
class Solution:
    def exchange(self, nums: List[int]) -> List[int]:
        j=len(nums)-1
        i=0
        while i<j:
            if nums[i]%2==0:
                if nums[j]%2==0:
                    j=j-1
                    continue
                else:
                    nums[i],nums[j]=nums[j],nums[i]
            i=i+1
        return nums
 

#22.py

# 输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。
class Solution:
    def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
        fast=head
        slow=head
        for i in range(k):
            fast=fast.next
        
        while fast:
            slow=slow.next
            fast=fast.next

        return slow

#24.py

# 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
# 示例:
# 输入: 1->2->3->4->5->NULL
# 输出: 5->4->3->2->1->NULL

# 限制:
# 0 <= 节点个数 <= 5000
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not head:return []
        p=head
        q=p.next
        while q:
            tmp=q.next
            q.next=p
            p=q
            q=tmp
        head.next=None
        return p

#25.py

# 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

# 示例1:

# 输入:1->2->4, 1->3->4
# 输出:1->1->2->3->4->4
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        l=ListNode(-1)
        head=l
        while l1 and l2:
            if l1.val<=l2.val:
                l.next=l1
                l1=l1.next
            else:
                l.next=l2
                l2=l2.next
            l=l.next
        
        while l1:
            l.next=l1
            l1=l1.next
            l=l.next
        while l2:
            l.next=l2
            l2=l2.next
            l=l.next
        return head.next

#26.py

# 输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

# B是A的子结构, 即 A中有出现和B相同的结构和节点值。

# 例如:
# 给定的树 A:

#      3
#     / \
#    4   5
#   / \
#  1   2
# 给定的树 B:

#    4 
#   /
#  1
# 返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

# 示例 1:

# 输入:A = [1,2,3], B = [3,1]
# 输出:false
# 示例 2:

# 输入:A = [3,4,5,1,2], B = [4,1]
# 输出:true
class Solution:
    def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
        def dfs(a,b):
            if not b:return True
            if not a or a.val!=b.val:return False
            return dfs(a.left,b.left) and dfs(a.right,b.right)

        if not A or not B:return False
        return dfs(A,B) or self.isSubStructure(A.left,B) or self.isSubStructure(A.right,B)

#27.py

# 请完成一个函数,输入一个二叉树,该函数输出它的镜像。

# 例如输入:

#      4
#    /   \
#   2     7
#  / \   / \
# 1   3 6   9
# 镜像输出:

#      4
#    /   \
#   7     2
#  / \   / \
# 9   6 3   1
class Solution:
    def mirrorTree(self, root: TreeNode) -> TreeNode:
        def dfs(root):
            if root is None:return []
            root.left,root.right=root.right,root.left
            if root.left:
                dfs(root.left)
            if root.right:
                dfs(root.right)
            return root
        return dfs(root)

#28.py

# 请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

# 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

#     1
#    / \
#   2   2
#  / \ / \
# 3  4 4  3
# 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

#     1
#    / \
#   2   2
#    \   \
#    3    3
class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        def dfs(L,R):
            if not L and not R:return True
            if not L or not R or L.val!=R.val:return False
            return dfs(L.right,R.left) and dfs(L.left,R.right)

        if not root:return True
        else:
            return dfs(root.left,root.right)

#29.py

# 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

#  

# 示例 1:

# 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
# 输出:[1,2,3,6,9,8,7,4,5]
# 示例 2:

# 输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
# 输出:[1,2,3,4,8,12,11,10,9,5,6,7]
class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        res = []
        while matrix:
            res.extend(matrix.pop(0))
            matrix=list(zip(*matrix))[::-1]
        return res

#30.py

# 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
# 示例:

# MinStack minStack = new MinStack();
# minStack.push(-2);
# minStack.push(0);
# minStack.push(-3);
# minStack.min();   --> 返回 -3.
# minStack.pop();
# minStack.top();      --> 返回 0.
# minStack.min();   --> 返回 -2.
class MinStack:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack=[]
        self.minstack=[]

    def push(self, x: int) -> None:
        self.stack.append(x)
        if not self.minstack or x<=self.minstack[-1]:
            self.minstack.append(x)

    def pop(self) -> None:
        x=self.stack.pop()
        if x==self.minstack[-1]:
            self.minstack.pop()     

    def top(self) -> int:
        return self.stack[-1]

    def min(self) -> int:
        return self.minstack[-1]

#31.py

# 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。

# 示例 1:

# 输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
# 输出:true
# 解释:我们可以按以下顺序执行:
# push(1), push(2), push(3), push(4), pop() -> 4,
# push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
# 示例 2:

# 输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
# 输出:false
# 解释:1 不能在 2 之前弹出。
class Solution:
    def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
        stack=[]
        p=0
        for item in pushed:
            stack.insert(0,item)
            while stack and popped[p]==stack[0]:
                p+=1
                stack.pop(0)
        
        return not stack

#32.py

# 从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
# 例如:
# 给定二叉树: [3,9,20,null,null,15,7],

#     3
#    / \
#   9  20
#     /  \
#    15   7
# 返回:

# [3,9,20,15,7]
class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        q=[]
        if root:
            q.append(root)
        res=[]
        while q:
            node=q.pop(0)
            res.append(node.val)
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)
        return res 

#32_2.py

# 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
# 例如:
# 给定二叉树: [3,9,20,null,null,15,7],

#     3
#    / \
#   9  20
#     /  \
#    15   7
# 返回其层次遍历结果:

# [
#   [3],
#   [9,20],
#   [15,7]
# ]

class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        q=[]
        if root:
            q.append(root)
        res=[]
        while q:
            node=q.pop(0)
            res.append(node.val)
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)

        return res 

#32_3.py

# 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
# 例如:
# 给定二叉树: [3,9,20,null,null,15,7],

#     3
#    / \
#   9  20
#     /  \
#    15   7
# 返回其层次遍历结果:

# [
#   [3],
#   [20,9],
#   [15,7]
# ]
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        q=[]
        if root:
            q.append([root])
        res=[]
        while q:
            nodelist=q.pop(0)
            
            level=[]
            t=[]
            for node in nodelist:
                t.append(node.val)
                if node.left:
                    level.append(node.left)
                if node.right:
                    level.append(node.right)
            if level:
                q.append(level)
            res.append(t)
        for i in range(len(res)):
            if i%2==1:
                res[i]=res[i][::-1]    
        return res 

#33.py

# 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
# 参考以下这颗二叉搜索树:

#      5
#     / \
#    2   6
#   / \
#  1   3
# 示例 1:

# 输入: [1,6,3,2,5]
# 输出: false
# 示例 2:

# 输入: [1,3,2,6,5]
# 输出: true

class Solution:
    def verifyPostorder(self, postorder: List[int]) -> bool:
        if not postorder or len(postorder) == 0:return True
        rootval=postorder[-1]
        n=len(postorder)
        mid=0
        for i in range(n):
            if postorder[i]>rootval:
                break
        mid=i
        for i in range(mid,n-1):
            if postorder[i]<rootval:
                return False
        left=True
        if mid>0:
            left=self.verifyPostorder(postorder[0:mid])
        right=True
        if i<n-1:
            right=self.verifyPostorder(postorder[mid:-1])
        return  left and right

#34.py

# 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。
# 示例:
# 给定如下二叉树,以及目标和 sum = 22,

#               5
#              / \
#             4   8
#            /   / \
#           11  13  4
#          /  \    / \
#         7    2  5   1
# 返回:

# [
#    [5,4,11,2],
#    [5,8,4,5]
# ]
class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
        if not root:return []
        res=[]
        def dfs(root,total,t):
            if not root.left and not root.right:
                print(t,sum,total)
                if total==sum:
                    res.append(t)
            #t=t+[root.val]
            if root.left:
                dfs(root.left,total+root.left.val,t+[root.left.val])   
            if root.right:
                dfs(root.right,total+root.right.val,t+[root.right.val]) 

        dfs(root,root.val,[root.val])
        return res

#35.py

#请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
class Node:
    def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
        self.val = int(x)
        self.next = next
        self.random = random

class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        def dfs(root):
            if not root:return
            if root in visited:
                return visited[root]
           
            copy=Node(root.val,None,None)
            visited[root]=copy
            copy.next=dfs(root.next)
            copy.random=dfs(root.random)

            return copy

        visited={}
        return dfs(head)

#36.py

#输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        def dfs(cur):
            if not cur:return
            dfs(cur.left)
            if self.pre:
                self.pre.right=cur
                cur.left=self.pre
            else:
                self.head=cur
            self.pre=cur
            dfs(cur.right)
            
        if not root:return
        self.pre=None
        dfs(root)
        self.head.left=self.pre
        self.pre.right=self.head
        return self.head

#37.py

#请实现两个函数,分别用来序列化和反序列化二叉树。
class Codec:

    def serialize(self, root):
        res=[]
        def dfs(root):
            if not root:
                res.append("#")
                return
            res.append(str(root.val))
            #if root.left:
            dfs(root.left)
            #if root.right:
            dfs(root.right)
        dfs(root)
        return ",".join(res)

    def deserialize(self, data):
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: TreeNode
        """
        d=iter(data.split(","))
        def dfs():
            
            s=next(d)
            if s=="#":return
            node=TreeNode(int(s))
            node.left=dfs()
            node.right=dfs()
            return node
        return dfs()

#38.py

# 输入一个字符串,打印出该字符串中字符的所有排列。
# 你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
class Solution:
    def permutation(self, s: str) -> List[str]:
        s="".join(sorted(s))
        res=[]
        def dfs(s,tmp):
            if len(s)==0:
                res.append(tmp)
            for i in range(len(s)):
                if i-1>=0 and s[i]==s[i-1]:
                    continue
                else:
                    dfs(s[0:i]+s[i+1:],tmp+s[i])
        dfs(s,"")
        return res
 

#39.py

# 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
# 你可以假设数组是非空的,并且给定的数组总是存在多数元素。
# 示例 1:
# 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
# 输出: 2

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        nums.sort()
        return nums[len(nums)//2]

你可能感兴趣的:(leetcode)