leetcode 树相关题目小结

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)。

扫描二维码关注公众号,回复: 963825 查看本文章

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)

猜你喜欢

转载自blog.csdn.net/IqqIqqIqqIqq/article/details/80293202