牛客 ⌈面试必刷 TOP 101⌋ -- Python 版 【更新中】

2023-06-10更新

BM12 单链表的排序

思路

  • 将数据存到list中,使用list自带的sort()函数排序,然后更新原来的链表数据。

代码

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 the head node
# @return ListNode类
#
class Solution:
    def sortInList(self , head: ListNode) -> ListNode:
        # write code here
        vallist=[]

        p=head

        while p:
            vallist.append(p.val)
            p=p.next
        print(vallist)
        vallist.sort()
        p=head
        for item in vallist:
            p.val=item
            p=p.next
        return head

BM13 判断一个链表是否为回文结构

思路

  • 读取链表中的值存入list,借助Pythonreversed函数,将list逆序,然后比较两个list是否一致。

代码

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 the head
# @return bool布尔型
#
class Solution:
    def isPail(self , head: ListNode) -> bool:
        # write code here
        list1=[]
        while head:
            list1.append(head.val)
            head=head.next
        
        list2=list(reversed(list1))
        print(list1)
        print(list2)
        if list1==list2:
            return True
        else:
            return False

BM14 链表的奇偶重排

思路

  • 遍历链表,使用双指针将奇项和偶项连起来,然后奇项链表的尾指偶项链表的头。

代码

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @return ListNode类
#
class Solution:
    def oddEvenList(self , head: ListNode) -> ListNode:
        # write code here
        
        pHead1=ListNode(-1)
        pHead2=ListNode(-1)
        pHead11=pHead1
        pHead22=pHead2
        i=1
        while head:
            if i%2==1:
                pHead1.next=head
                pHead1=pHead1.next
            else:
                pHead2.next=head
                pHead2=pHead2.next
            head=head.next
            # print(head.val)
            i=i+1
        pHead1.next=None
        pHead2.next=None
        pHead1.next=pHead22.next

        return pHead11.next

BM15 删除有序链表中重复的元素-I

思路

  • 双指针,一个为head指针,一个指向head指针指向节点的前一个节点。遍历head链表,比较head所指的值和fhead所指的值,如果相同,则重复,将此节点从链表中删除;如果不同,则不重复,fheadhead分别向后移一位。

代码

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @return ListNode类
#
class Solution:
    def deleteDuplicates(self , head: ListNode) -> ListNode:
        # write code here
        if not head:
            return head
        rhead=head
        fhead=head
        head=head.next
        while head:
            if head.val==fhead.val:
                fhead.next=head.next
            else:
                fhead=head
            head=head.next
        return rhead

BM16 删除有序链表中重复的元素-II

思路

  • 双指针,fheadhead,初始情况下 fhead.next == head。使用flag标记是否出现重复值。使用head指针遍历链表,如果head的值和head.next的值一样,将flag标记为1head后移;如果不一样且flag == 1,那么fhead.next指向head.nexthead指向head.next;如果不一样且flag==0,那么fheadhead同时后移一位。在遍历结束后,注意flag==1的情况。

代码

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @return ListNode类
#
class Solution:
    def deleteDuplicates(self , head: ListNode) -> ListNode:
        # write code here
        if not head or not head.next:
            return head
        
        rhead=ListNode(0)
        rhead.next=head
        fhead=rhead
        flag=0
        while head.next:
            print(head.val)
            if head.val==head.next.val:
                flag=1
            elif flag==0 and head.val!=head.next.val:
                fhead=head
                flag=0
            elif flag==1 and head.val!=head.next.val:
                print("x")
                fhead.next=head.next
                flag=0
            head=head.next
        if flag==1:
            fhead.next=None
        return rhead.next

BM17 二分查找-I

思路

代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param nums int整型一维数组 
# @param target int整型 
# @return int整型
#
class Solution:
    def search(self , nums: List[int], target: int) -> int:
        # write code here
        if len(nums)==0:
            return -1
        left=0
        right=len(nums)-1
        while left<=right:
            middle=left+int((right-left)/2)
            print(nums[middle])
            if nums[middle]==target:
                return middle
            elif nums[middle]<target:
                left=middle+1
            elif nums[middle]>target:
                right=middle-1
        return -1

BM18 二维数组中的查找

思路

  • 二维数组左下角的值ld具备的属性:当前列的最大值,当前行的最小值,将ld与target比较:
    • target==ld:找到该值
    • target>ld:target比当前列的最大值大,右移一列
    • target<ld:target比当前行的最小值小,上移一行
    • 循环结束条件:找到目标值或ld移除二维数组

代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param target int整型 
# @param array int整型二维数组 
# @return bool布尔型
#
class Solution:
    def Find(self , target: int, array: List[List[int]]) -> bool:
        # write code here
        h=len(array)
        if h==0:
            return False
        w=len(array[0])
        if h==1 and w==1:
            return False
        ld_i=h-1
        ld_j=0
        while ld_i>=0 and ld_j<w:
            if target ==array[ld_i][ld_j]:
                return True
            elif target<array[ld_i][ld_j]:
                ld_i=ld_i-1
            elif target>array[ld_i][ld_j]:
                ld_j=ld_j+1
        return False

BM19 寻找峰值

思路

  • 这道题,只能说很抽象,因为左右两边都是最小值,所以如果最开始是递减或最末尾是递增,那么也算是峰值。举两个例子:
    • [2,4,1,2,7,8,4],输出5
    • [2,4,1,2,7,8,9],输出6
    • [4,3,2,1],输出0
  • 参考链接:(寻找峰值(二分法)_osillto的博客-CSDN博客

代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param nums int整型一维数组 
# @return int整型
#
class Solution:
    def findPeakElement(self , nums: List[int]) -> int:
        left,right = 0,len(nums)-1
        while left<right:
            mid = (left+right)//2
            if nums[mid] < nums[mid+1]: left = mid+1
            else: right = mid
        return left

BM20 数组中的逆序对

思路

  • 首先,全遍历不行,复杂度不满足要求
  • 然后参考合并排序思路,进行逆数对统计。
  • 思路参考:
    在这里插入图片描述
  • 代码参考:
    在这里插入图片描述
  • Python 列表逆序方法:(Python 列表逆序排列的 3 种方式_python中的逆序排列_Nick Blog的博客-CSDN博客
    Python 3.11.3 (tags/v3.11.3:f3909b8, Apr  4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> arr=[1,2,3,4,5,6,7]
    >>> arr[::-1]
    [7, 6, 5, 4, 3, 2, 1]
    >>> arr[:5]
    [1, 2, 3, 4, 5]
    >>> arr[:5][::-1]
    [5, 4, 3, 2, 1]
    >>>
    

代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param data int整型一维数组 
# @return int整型
#
class Solution:
    def __init__(self):
        self.res=0
        self.kmod=1000000007
    
    def mergeSort(self,arr):
        n=len(arr)
        if n==1:
            return arr
        mid =n//2
        leftList=self.mergeSort(arr[:mid])
        rightList=self.mergeSort(arr[mid:])

        temp=[]
        i=len(leftList)-1
        j=len(rightList)-1
        while i>=0 and j>=0:
            if leftList[i]>=rightList[j]:
                temp.append(leftList[i])
                i=i-1
                self.res=(self.res+j+1)%self.kmod
            else:
                temp.append(rightList[j])
                j=j-1
        if i==-1:
            temp+=rightList[:j+1][::-1]
        elif j==-1:
            temp+=leftList[:i+1][::-1]
        return temp[::-1]



    def InversePairs(self , data: List[int]) -> int:
        # write code here
        self.mergeSort(data)
        return self.res

BM21 旋转数组的最小数字

思路

  • 二分查找,但是判断条件有些混乱。再理一下:
    • 如果中间的值等于左边的值:那么最小值肯定不在mid左边,所以left=mid
    • 如果中间的值等于右边的值:那么最小值肯定不在mid右边,所以right=mid
    • 如果左边的值大于中间的值:那么最小值一定在左边,所以right=mid
    • 如果右边的值小于中间的值:那么最小值一定在右边,所以left=mid
    • 当left+1==right的时候,两个数中较小的值是最小值

代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param rotateArray int整型一维数组 
# @return int整型
#
class Solution:
    def minNumberInRotateArray(self , rotateArray: List[int]) -> int:
        # write code here
        left=0
        right=len(rotateArray)-1
        while(left+1<right):
            mid=(left+right)//2
            print(left,mid,right)
            if rotateArray[mid]>rotateArray[mid+1]:
                return rotateArray[mid+1]
            elif rotateArray[mid]==rotateArray[len(rotateArray)-1] or rotateArray[mid]<rotateArray[0]:
                right=mid
            elif rotateArray[mid]==rotateArray[0] or rotateArray[mid]>rotateArray[len(rotateArray)-1]:
                left=mid
        if rotateArray[left]<rotateArray[right]:
            return rotateArray[left]
        else:
            return rotateArray[right]

BM22 比较版本号

思路

  • 使用python字符串的split函数,将版本号基于“.”拆分成数组,逐个比较。
  • 参考链接:https://blog.csdn.net/qq_61959780/article/details/127690872
  • 代码参考:GPT

代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 比较版本号
# @param version1 string字符串 
# @param version2 string字符串 
# @return int整型
#
class Solution:
    def compare(self , version1: str, version2: str) -> int:
        # write code here
        lst1=version1.split(".")
        lst2=version2.split(".")
        i=0
        while i<len(lst1) or i<len(lst2):
            data1=lst1[i] if i<len(lst1) else 0
            data2=lst2[i] if i<len(lst2) else 0
            if int(data1)<int(data2):
                return -1
            elif int(data1)>int(data2):
                return 1
            i+=1
        return 0

BM 23 二叉树前序遍历

思路

  • 递归

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型一维数组
#
class Solution:
    def preorderTraversal(self , root: TreeNode) -> List[int]:
        # write code here
        res=[]
        def dfs(node):
            if not node:
                return 
            res.append(node.val)
            dfs(node.left)
            dfs(node.right)
        dfs(root)
        return res   

BM 24 二叉树的中序遍历

思路

  • 先读取节点值,再遍历左子树,再遍历右子树。
  • 代码和BM23只有读取节点值的位置不同。

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型一维数组
#
class Solution:
    def inorderTraversal(self , root: TreeNode) -> List[int]:
        # write code here
        res=[]
        def dfs(node):
            if not node:
                return 
            dfs(node.left)
            res.append(node.val)

            dfs(node.right)
        dfs(root)
        return res   

BM 25 二叉树的后序遍历

思路

  • 先遍历左子树,再遍历右子树,再读取节点值。
  • 代码和BM23只有读取节点值的位置不同。

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型一维数组
#
class Solution:
    def postorderTraversal(self , root: TreeNode) -> List[int]:
        # write code here
        res=[]
        def dfs(node):
            if not node:
                return 
            dfs(node.left)
            dfs(node.right)
            res.append(node.val)
        dfs(root)
        return res   

BM26 求二叉树的层序遍历

思路

  • GPT生成代码及思路
  • 其中,TreeNode是二叉树节点的定义,Solution中的levelOrder方法是层序遍历的实现,使用了队列的方式。层序遍历的顺序是按照从上到下、从左到右的顺序访问每个节点,因此在实现中使用一个队列来存储当前层的节点,在访问当前层的节点时,将其子节点加入队列中,以便在下一层访问。

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return int整型二维数组
#
class Solution:
    def levelOrder(self , root: TreeNode) -> List[List[int]]:
        # write code here
        if not root:
            return []
        res = []
        queue = [root]
        while queue:
            level = []
            for _ in range(len(queue)):
                node = queue.pop(0)
                level.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            res.append(level)
        return res

BM27 按之字形顺序打印二叉树

思路

  • 层序遍历,同时利用[::-1]实现逆序输出。
  • 列表逆序的三种方式:
    • lst[::-1]
    • list(reversed(lst))
    • lst.reverse() 注:lista.reverse() 这一步操作的返回值是一个None,其作用的结果,需要通过打印被作用的列表才可以查看出具体的效果

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param pRoot TreeNode类 
# @return int整型二维数组
#
class Solution:
    def Print(self , pRoot: TreeNode) -> List[List[int]]:
        # write code here
        if not pRoot:
            return []
        res=[]
        queue=[pRoot]
        flag=1
        while queue:
            layer=[]
            for _ in range(len(queue)):
                node=queue[0]
                queue.pop(0)
                layer.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            if flag:
                res.append(layer)
                flag=0
            else:
                res.append(layer[::-1])
                flag=1
        return res

BM28 二叉树的最大深度

思路

  • dfs,同时记录当前分支上最大深度,返回左右子树中较大值。

代码

  • 代码1,函数里面套函数套函数,冗余,精简版看代码2
    # class TreeNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    #
    # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    #
    # 
    # @param root TreeNode类 
    # @return int整型
    #
    class Solution:
        def maxDepth(self , root: TreeNode) -> int:
            # write code here
            if not root:
                return 0
            def dfs(troot:TreeNode,deep=0) -> int:
                if not troot:
                    return deep
                deep=deep+1
                deepl=dfs(troot.left,deep)
                deepr=dfs(troot.right,deep)
                return deepl if deepl>deepr else deepr
            return dfs(root)
    
  • 代码2
    # class TreeNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    #
    # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    #
    # 
    # @param root TreeNode类 
    # @return int整型
    #
    class Solution:
        def maxDepth(self , root: TreeNode) -> int:
            # write code here
            if not root:
                return 0
            else:
                return 1+max(self.maxDepth(root.left),self.maxDepth(root.right))
    

BM29 二叉树中和为某一值的路径(一)

思路

  • 注意一个点,如果初始树为空,sum为0的情况,要单独考虑。
  • 如何判定到达叶子结点:not root.left and not root.right 等同于 not(root.left or root.left)

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @param sum int整型 
# @return bool布尔型
#
class Solution:
    def hasPathSum(self , root: TreeNode, sum: int) -> bool:
        # write code here
        if not root:
            return False
        elif not root.left and not root.right and sum==root.val:
            return True
        elif self.hasPathSum(root.left,sum-root.val):
            return True
        else:
            return self.hasPathSum(root.right,sum-root.val)

BM30 二叉搜索树与双向链表

思路

  • 思路:
    在这里插入图片描述
    在这里插入图片描述
  • 参考:
    在这里插入图片描述

代码

  • 正确代码:
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

#
# 
# @param pRootOfTree TreeNode类 
# @return TreeNode类
#
class Solution:
    def Convert(self , pRootOfTree ):
        # write code here
        if not pRootOfTree:
            return
        
        left=self.Convert(pRootOfTree.left)

        p=left

        while p and p.right:
            p=p.right
        
        if left:
            pRootOfTree.left=p
            p.right=pRootOfTree
        
        right=self.Convert(pRootOfTree.right)

        if right:
            pRootOfTree.right=right
            right.left=pRootOfTree
        
        return left if left else pRootOfTree
  • chatgpt给的代码:
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

#
# 
# @param pRootOfTree TreeNode类 
# @return TreeNode类
#
class Solution:
    def Convert(self , pRootOfTree ):
        # write code here
        if not pRootOfTree:
            return None
        nodes = []
        self.inorder(pRootOfTree, nodes)
        for i in range(len(nodes) - 1):
            nodes[i].right = nodes[i + 1]
            nodes[i + 1].left = nodes[i]
        return nodes[0]

    def inorder(self, root, nodes):
        if not root:
            return
        self.inorder(root.left, nodes)
        nodes.append(root)
        self.inorder(root.right, nodes)
  • 自己写的错误代码:
class Solution:
    def Convert(self , pRootOfTree ):
        # write code here
        if not pRootOfTree:
            return pRootOfTree
        elif not pRootOfTree.left and not pRootOfTree.right:
            return pRootOfTree
        def calcAZ(root: TreeNode):
            if not root.left:
                aa=root
            else:
                aa=calcAZ(root.left)[0]
            if not root.right:
                zz=root
            else:
                zz=calcAZ(root.right)[1]
            return aa,zz
        if pRootOfTree.left and pRootOfTree.right:
            newroot,zz=calcAZ(pRootOfTree.left)
            pRootOfTree.left=zz
            zz.right=pRootOfTree
            aa=calcAZ(pRootOfTree.right)[0]
            pRootOfTree.right=aa
            aa.left=pRootOfTree
        elif not pRootOfTree.left:
            aa=calcAZ(pRootOfTree.right)[0]
            pRootOfTree.right=aa
            aa.left=pRootOfTree 
            newroot=pRootOfTree
        elif not pRootOfTree.right:
            newroot,zz=calcAZ(pRootOfTree.left)
            pRootOfTree.left=zz
            zz.right=pRootOfTree
        return newroot

BM31 对称的二叉树

思路

  • 递归,首先判断根节点是否存在(不存在肯定对称)
    • 如果存在,
      • 以左右节点为根节点,判断这两棵子树是否对称
      • 首先判断左右节点是否都不存在
        • 如果都不存在,那么返回true
      • 判断左右节点是否都存在且值都一样
        • 如果有一点不满足,返回FALSE
      • 如果都满足:
        • 判断左节点的左子节点和右节点的右子节点是否对称
        • 判断左节点的右子节点和右节点的左子节点是否对称
        • 如果都对称,那么说明该根节点对应的树对称,返回true;否则不对称,返回false
    • 如果不存在(也即是递归结束的条件之一,返回true)

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param pRoot TreeNode类 
# @return bool布尔型
#
class Solution:
    def isSymmetrical(self , pRoot: TreeNode) -> bool:
        # write code here
        def areMirror(left,right)->bool:
            if not (left or right):
                return True
            elif (not left and right) or (not right and left) or left.val!=right.val:
                return False
            else:
                return areMirror(left.left,right.right) and areMirror(left.right,right.left)
        if not pRoot:
            return True
        else:
            return areMirror(pRoot.left,pRoot.right)

BM32 合并二叉树

思路

  • 将t2合并到t1上
    • 如果t1或者t2中有一个为空,那就返回另一个根节点
    • 否则,
      • t1的值等于t1加t2的值
      • t1的左节点等于t1的左节点与t2的左节点合并
      • t1的右节点等于t1的右节点与t2的右节点合并
      • 返回t1

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param t1 TreeNode类 
# @param t2 TreeNode类 
# @return TreeNode类
#
class Solution:
    def mergeTrees(self , t1: TreeNode, t2: TreeNode) -> TreeNode:
        # write code here
        if not t1 or not t2:
            return t1 if t1 else t2
        else:
            t1.val=t1.val+t2.val
            t1.left=self.mergeTrees(t1.left,t2.left)
            t1.right=self.mergeTrees(t1.right,t2.right)
            return t1

BM33 二叉树的镜像

思路

  • 思路一(对应代码1,2)
    在这里插入图片描述

代码

  • 代码1:空间复杂度O(n)
    # class TreeNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    #
    # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    #
    # 
    # @param pRoot TreeNode类 
    # @return TreeNode类
    #
    class Solution:
        def Mirror(self , pRoot: TreeNode) -> TreeNode:
            # write code here
            if not pRoot:
                return pRoot
            pRoot.left, pRoot.right = self.Mirror(pRoot.right), self.Mirror(pRoot.left)
            # 注意:同时赋值
            return pRoot
    
  • 代码2:
    class Solution:
        def Mirror(self, pRoot: TreeNode) -> TreeNode:
            # write code here
            if not pRoot:
                return pRoot
            tmp = pRoot.left
            pRoot.left = pRoot.right
            pRoot.right = tmp
            self.Mirror(pRoot.right)
            self.Mirror(pRoot.left)
            # 注意:不同时赋值
            return pRoot
    
  • 代码3:空间复杂度O(1)
    class Solution:
        def Mirror(self , pRoot: TreeNode) -> TreeNode:
            # write code here
            if pRoot:
                stack = [pRoot]
                while stack:
                    curr = stack.pop()
                    curr.left, curr.right = curr.right, curr.left
                    if curr.right:
                        stack.append(curr.right)
                    if curr.left:
                        stack.append(curr.left)
            return pRoot
    

BM34 判断是不是二叉搜索树

思路

  • 中序深度优先遍历,遍历结果从小到大排序后和排序前是否一致

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return bool布尔型
#
class Solution:
    def isValidBST(self , root: TreeNode) -> bool:
        # write code here
        nodes=[]

        def dfs(pRoot: TreeNode):
            if not pRoot: return
            dfs(pRoot.left)
            nodes.append(pRoot.val)
            dfs(pRoot.right)
            return
        dfs(root)
        print(nodes)
        print(sorted(nodes))
        if nodes==sorted(nodes):
            return True
        else:
            return False

BM35 判断是不是完全二叉树

思路

  • 如代码中的逻辑

代码

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param root TreeNode类 
# @return bool布尔型
#
class Solution:
    def isCompleteTree(self , root: TreeNode) -> bool:
        # write code here
        if not root: return True

        stack=[root]

        while stack:
            tmp=stack[0]
            stack.pop(0)
            if tmp.right:
                if tmp.left:
                    stack.append(tmp.left)
                    stack.append(tmp.right)
                else:
                    return False
            else:
                if tmp.left:
                    stack.append(tmp.left)
                break

        while stack:
            tmp=stack[0]
            stack.pop(0)
            if tmp.left or tmp.right:
                return False


        return True

BM 62 斐波那契数列

思路

  • 思路1:按照公式循环计算。
  • 思路2:递归的方式,如果直接使用递归会超时,使用一个字典记录已经计算过的值。

代码

  • 代码1
    #
    # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    #
    # 
    # @param n int整型 
    # @return int整型
    #
    class Solution:
        def Fibonacci(self , n: int) -> int:
            # write code here
            if n==1 or n==2:
                return 1
            fib_1=1
            fib_2=1
            fib_3=0
            for i in range(2,n):
                fib_3=fib_1+fib_2
                fib_1=fib_2
                fib_2=fib_3
            return fib_3
    
    
  • 代码2
    #
    # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    #
    # 
    # @param n int整型 
    # @return int整型
    #
    class Solution:
        def __init__(self) -> None:
            # 用一个字典记录F(n)有没有计算过
            self.f = dict()
            self.f[1]=1
            self.f[2]=1
        def Fibonacci(self , n: int) -> int:
            # write code here
            if n==1 or n==2:
                return self.f[n]
            else:
                if n-1 not in self.f:
                    self.f[n-1]=self.Fibonacci(n-1)
    
                if n-2 not in self.f:
                    self.f[n-2]=self.Fibonacci(n-2)
                return self.f[n-1]+self.f[n-2]
    

BM42 用两个栈实现队列

思路

  • push:只往栈里1append
  • pop:
    • 如果栈2中有元素,那么从栈2中pop
    • 如果栈2中没有元素,那么将栈1中的所有元素pop出,append进栈2中,然后从栈2中pop

代码

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []
    def push(self, node):
        # write code here
        self.stack1.append(node)
        return 
    def pop(self):
        if len(self.stack2)==0:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

BM43 包含min函数的栈

思路

  • 两个栈

代码

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.stack=[]
        self.minvalue=[]

    def push(self, node):
        # write code here
        self.stack.append(node)
        if not self.minvalue:
            self.minvalue.append(node)
        else:
            if node<=self.minvalue[-1]:
                self.minvalue.append(node)
            else:
                self.minvalue.append(self.minvalue[-1])
    def pop(self):
        # write code here
        self.stack.pop()
        self.minvalue.pop()
    def top(self):
        # write code here
        return self.stack[-1]
    def min(self):
        # write code here
        return self.minvalue[-1]

BM63 跳台阶

思路

  • 递归
  • 直接递归会超时
  • 记忆化搜索
  • 到底什么是递归?什么是动态规划?

代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param number int整型 
# @return int整型
#
class Solution:
    def __init__(self) -> None:
        # 用一个字典记录F(n)有没有计算过
        self.f = dict()
        self.f[1]=1
        self.f[2]=2
    def jumpFloor(self , number: int) -> int:
        # write code here
        if number in self.f:
            return self.f[number]
        else:
            self.f[number-1]=self.f[number-1] if number-1 in self.f else self.jumpFloor(number-1)
            self.f[number-2]=self.f[number-2] if number-2 in self.f else self.jumpFloor(number-2)
            return self.f[number-1]+self.f[number-2]

BM64

思路

  • 最开始利用递归,使用代码2,但是内存超限
  • 然后使用gpt生成的代码1,利用for循环,成功
  • 两个代码的不同:我是逆着考虑,gpt是正着考虑,不过不用for循环
  • 嗯嗯,gpt比我聪明。。。。

代码

  • 代码1
    class Solution:
        def minCostClimbingStairs(self, cost: List[int]) -> int:
            n = len(cost)
            dp = [0] * n
            dp[0], dp[1] = cost[0], cost[1]
            for i in range(2, n):
                dp[i] = min(dp[i-1], dp[i-2]) + cost[i]
            return min(dp[n-1], dp[n-2])
    
  • 代码2
    #
    # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    #
    # 
    # @param cost int整型一维数组 
    # @return int整型
    #
    class Solution:
        def __init__(self) -> None:
            self.eco={}
        def minCostClimbingStairs(self , cost: List[int]) -> int:
            # write code here
            if len(cost)<=1:
                self.eco[len(cost)]=0
                return self.eco[len(cost)]
    
            elif len(cost)==2:
                self.eco[len(cost)]=min(cost[0],cost[1])
                return self.eco[len(cost)]
            else:
                self.eco[len(cost[:-2])]=self.eco[len(cost[:-2])] if len(cost[:-2]) in self.eco else self.minCostClimbingStairs(cost[:-2])
                self.eco[len(cost[:-1])]=self.eco[len(cost[:-1])] if len(cost[:-1]) in self.eco else self.minCostClimbingStairs(cost[:-1])
                return min(self.eco[len(cost[:-2])]+cost[-2],self.eco[len(cost[:-1])]+cost[-1])
    
阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
题目要求:给定一个二叉树和一个整数target,找出所有从根节点到叶子节点路径之和等于target的路径。 解题思路:可以使用深度优先搜索(DFS)的方法来解决该问题。首先定义一个辅助函数来进行递归搜索,该辅助函数的参数包括当前节点、当前路径、当前路径的和以及目标和。在搜索过程,需要维护一个数组来保存当前节点到根节点的路径。搜索过程如下: 1. 如果当前节点为空,则返回。 2. 将当前节点的值添加到当前路径。 3. 将当前节点的值累加到当前路径的和。 4. 如果当前节点是叶子节点,且当前路径的和等于目标和,则将当前路径添加到结果。 5. 递归地搜索当前节点的左子树和右子树,并传递更新后的当前路径和当前路径的和。 最后,在主函数调用辅助函数,并返回结果即可。 以下是题目的完整代码实现: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def pathSum(root, target): def dfs(node, path, path_sum, target, res): if not node: return path.append(node.val) path_sum += node.val if not node.left and not node.right: # 当前节点是叶子节点 if path_sum == target: res.append(path[:]) # 注意需要复制一份path,否则会出现问题 dfs(node.left, path, path_sum, target, res) dfs(node.right, path, path_sum, target, res) path.pop() # 回溯到父节点,去掉当前节点 path_sum -= node.val res = [] dfs(root, [], 0, target, res) return res ``` 这样就能找出所有满足路径和等于目标和的路径了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

froM_C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值