Leetcode个人刷题记录与解答思路(用于个人纪录与分享)

刷题之前,要知道leetcode的标签主要包括什么:

一. 算法问题主要包括:

分治, 二分查找, 贪心算法

排序问题包括:快速排序, 归并排序, 计数排序

搜索问题包括: 回溯, 递归, 深度优先, 广度优先, 二叉树搜索

图论问题: 最短路径, 最小生成树

动态规划: 背包问题,最长子序列

二. 数据结构问题主要包括:

数组与链表

栈与队列

哈希表

树与图

字符串

三. 下面开始每日记录题目与思考总结:

二叉树

22.03.04:

98. 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效二叉搜索树定义如下:

    节点的左子树只包含 小于 当前节点的数。
    节点的右子树只包含 大于 当前节点的数。
    所有左子树和右子树自身必须也是二叉搜索树

解题思路: 采用中序遍历的方法。中序遍历: 左中右。其中,左 小于 中,中 小于 右。将二叉树进行中序遍历,每个值存入stack中,查看stack的值是否为有序

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        res=[]
        def help(root):
            if not root:  return None
            help(root.left)
            res.append(root.val)
            help(root.right)
        help(root)
        print(res)
        for i in range(len(res)-1):
            if res[i]>=res[i+1]:
                return False
        return True

 其中,中序遍历算法模板如下:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
    res=[]
    def midhelp(root):
        if not root.left or not root.right:  return None
        midhelp(root.left)
        res.append(root.val)
        midhelp(root.right)
    midhelp(root)    
    

110. 给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

思路1: 计算出每个节点的左右最大深度,并对节点进行遍历(自顶而下)

计算节点最大深度代码如下:

def maxdeep(root: TreeNode):
    if not root:
        return 0
    return max(maxdeep(root.left),maxdeep(root.right))+1

题解代码如下:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def maxdeep(root: TreeNode):
            if not root:
                return 0
            return max(maxdeep(root.left), maxdeep(root.right))+1
        if not root: return True
        return abs(maxdeep(root.left)-maxdeep(root.right))<=1 and self.isBalanced(root.left) and self.isBalanced(root.right)

存在的问题: 每经过一个root,都要循环一边,非常耗时。时间复杂度为O(n方)

更新的思路:从底而上,但是我写不出来 ToT

22.03.05

114. 给你二叉树的根结点 root ,请你将它展开为一个单链表:

    展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。

解题思路1:先将二叉树用前序遍历,将每个节点存放在一个列表中(注意:存放的是节点,不是int值),之后遍历列表,让当前值等于新建的root,下一个值等于新建root.right, root.left为None

class Solution:
    def flatten(self, root: TreeNode) -> None:
        a=list()
        def previous(root:TreeNode):
            if root:
                a.append(root)
                previous(root.left)
                previous(root.right)
        previous(root)
        for i in range(len(a)-1):
            p,c=a[i],a[i+1]
            p.left=None
            p.right=c

其中,前序遍历的方法为:

def previous(root:TreeNode):
   if root:
       if not root:
           return None
       a.append(root)
       previous(root.left)
       previous(root.right)
        

        112. 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

题解思路:

22.03.11

111. 计算二叉树最小深度

解题思路:二叉树最小深度定义为根节点到叶子节点的最小距离。那么如果遇到如:[1,2], [1,Null, 2]这样的二叉树,其最小深度应该为2

流程如下:如果二叉树为空,返回0。如果只有根节点,返回1。 如果一侧无节点,返回有节点一侧的最小深度。代码如下:

# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def minDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        if not root.left and not root.right:
            return 1
        if not root.left:
            return 1 + self.minDepth(root.right)
        if not root.right:
            return 1 + self.minDepth(root.left)
 
        return 1 + min(self.minDepth(root.left),self.minDepth(root.right))

二分查找

22.03.09

33. 题目描述:整数数组 nums 按升序排列,数组中的值互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1

解题思路: 典型的二分查找需要数组由小到大排列,此题在不确定的位置将数组旋转,我们需要在得到的新数组中找target。将数组一分为二后,一定有一般是有序数组,一半是旋转数组。那么我们将有序的一部分用二分查找,旋转数组部分再进行分割。

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        if not nums: return -1
        l, r= 0, len(nums)-1
        while l<= r:
            m= (l+r)//2
            if target==nums[m]:
                return m
            if nums[0]<=nums[m]:
                if nums[l]<=target<nums[m]:
                    r=m-1
                else: l=m+1
            else: 
                if nums[m]<target<=nums[r]:
                    l=m+1
                else: r=m-1
        return -1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值