leetcode 树相关题目小结

本文解析了LeetCode上的三个二叉树经典问题:验证二叉搜索树的有效性、求不同结构的二叉搜索树数量及判断二叉树是否平衡。通过对这些问题的深入探讨,不仅介绍了相关算法的设计思路,还提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

leetcode 98. Validate Binary Search Tree
Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than the node’s key.
Both the left and right subtrees must also be binary search trees.

分析:
由于二叉搜索树中序遍历的结果是单调递增序列,因此可以对中序遍历后的数组进行检查,若存在前面一个数大于或等于(根据题目的定义)后面一个数则不是二叉搜索树,直接返回即可。

class Solution:
    # @param root, a tree node
    # @return a boolean
    def isValidBST(self, root):
        output = []
        self.inOrder(root, output)
        for i in range(1, len(output)):
            if output[i-1] >= output[i]:
                return False
        return True
    def inOrder(self, root, output):
        if root is None:
            return        
        self.inOrder(root.left, output)
        output.append(root.val)
        self.inOrder(root.right, output)

leetcode 96. Unique Binary Search Trees
Given n, how many structurally unique BST’s (binary search trees) that store values 1 … n?

Example:

Input: 3
Output: 5
Explanation: Given n = 3, there are a total of 5
unique BST’s:

这里写图片描述

分析:
这道题要求可行的二叉查找树的数量,其实二叉查找树可以任意取根,只要满足中序遍历有序的要求就可以。从处理子问题的角度来看,选取一个结点为根,就把结点切成左右子树,以这个结点为根的可行二叉树数量就是左右子树可行二叉树数量的乘积,所以总的数量是将以所有结点为根的可行结果累加起来。写成表达式如下:
这里写图片描述

这正是卡特兰数的一种定义方式,是一个典型的动态规划的定义方式(根据其实条件和递推式求解结果)。所以思路也很明确了,维护量res[i]表示含有i个结点的二叉查找树的数量。根据上述递推式依次求出1到n的的结果即可。
时间上每次求解i个结点的二叉查找树数量的需要一个i步的循环,总体要求n次,所以总时间复杂度是O(1+2+…+n)=O(n^2)。空间上需要一个数组来维护,并且需要前i个的所有信息,所以是O(n)。代码如下:

public int numTrees(int n) {  
    if(n<=0)  
        return 0;  
    int[] res = new int[n+1];  
    res[0] = 1;  
    res[1] = 1;  
    for(int i=2;i<=n;i++)  
    {  
        for(int j=0;j<i;j++)  
        {  
            res[i] += res[j]*res[i-j-1];  
        }  
    }  
    return res[n];  
} 

这种求数量的题目一般都容易想到用动态规划的解法,这道题的模型正好是卡特兰数的定义。当然这道题还可以用卡特兰数的通项公式来求解,这样时间复杂度就可以降低到O(n)。

leetcode 110. Balanced Binary Tree
Given a binary tree, determine if
it is height-balanced. For this problem, a height-balanced binary tree
is defined as: a binary tree in which the depth of the two subtrees of
every node never differ by more than 1.

分析:
平衡二叉搜索树具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。如果通过先求出高度再判断,时间复杂度将会达到O(n^2).如果边球高度边判断,可以将时间复杂度降到O(n)。

class Solution_recursive_without_extra_variable:
    def isBalanced(self, root):
        def dfs(root):
            if root is None:
                return 0
            left = dfs(root.left)
            right = dfs(root.right)
            if left == -1 or right == -1 or abs(left - right) > 1:
                return -1
            return max(left, right) + 1
        return dfs(root) != -1

leetcode 200. Number of Islands
Given a 2d grid map of ‘1’s (land) and ‘0’s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

11110
11010
00000

Output: 1
Example 2:

Input:
11000
00100
00011

Output: 3

分析:
如果我们每遇到一个陆地,就将属于该陆地的所有领域都标记为已经遍历过。那么下一次遇到一块新陆地的时候,该陆地一定是属于另一个版块。这种算法可以通过深度优先算法思想来实现。一旦遇到一块陆地,就递归的对上下左右的领域进行访问。

def numIslands(self, grid):
    if not grid:
        return 0

    count = 0
    for i in range(len(grid)):
        for j in range(len(grid[0])):
            if grid[i][j] == '1':
                self.dfs(grid, i, j)
                count += 1
    return count

def dfs(self, grid, i, j):
    if i<0 or j<0 or i>=len(grid) or j>=len(grid[0]) or grid[i][j] != '1':
        return
    grid[i][j] = '#'
    self.dfs(grid, i+1, j)
    self.dfs(grid, i-1, j)
    self.dfs(grid, i, j+1)
    self.dfs(grid, i, j-1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值