Different binary search trees II --- leetcode question 95

preface

LeetCode question 95 is a wonderful existence. Today, I'd like to share some more detailed ideas and methods to solve the problem.

Tip: if there is any error, please contact me to correct it. I hope you will give me your advice

1, Title Description

According to the official title overview of LeetCode, the general meaning of this title is: give you an integer n, please generate and return all different binary search trees composed of N nodes with different node values from 1 to n. You can return answers in any order.

2, Problem analysis and problem solving thinking analysis

1. Binary search tree

In short, a binary search tree means that the values of all nodes of the left subtree of the root node are smaller than it, and the values of all nodes of the right subtree are larger than it. Such a binary tree is called a binary search tree.

2. Problem analysis

Given a random number n, let's find all binary search trees with node values from 1 to N and return them all.
First:
We can know from the title that the root node is from 1 to N, that is, every point in the range of [1, n] may be a root node.

Second:
There will be left and right subtrees under each root node, and the child nodes of the root nodes of the left and right subtrees can be regarded as the root nodes of the left and right subtrees. Assuming that the current root node is point a, the values of the root nodes of the left and right subtrees are: the root node of the left subtree: 1 ~ (a-1); The root node of the right subtree is: (a+1) ~ n.


Third:
Similarly, continue according to the idea in Second until all points are traversed. That is, the process of recursion.

3. Code display

Python code:

# 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 generateTrees(self, n: int) -> List[TreeNode]:
        def generateTrees(start, end):
            if start > end:
                return [None]

            allTrees = []
            for i in range(start, end + 1):  # Enumerate possible root nodes
                # Obtain all feasible left subtree sets
                leftTrees = generateTrees(start, i - 1)

                # Obtain all feasible right subtree sets
                rightTrees = generateTrees(i + 1, end)

                # Select a left subtree from the left subtree set and a right subtree from the right subtree set and splice them to the root node
                for l in leftTrees:
                    for r in rightTrees:
                        currTree = TreeNode(i)
                        currTree.left = l
                        currTree.right = r
                        allTrees.append(currTree)

            return allTrees

        return generateTrees(1, n) if n else []

C + + Code:

class Solution {
public:
    vector<TreeNode*> generateTrees(int start, int end) {
        if (start > end) {
            return { nullptr };
        }
        vector<TreeNode*> allTrees;
        // Enumerate possible root nodes
        for (int i = start; i <= end; i++) {
            // Obtain all feasible left subtree sets
            vector<TreeNode*> leftTrees = generateTrees(start, i - 1);

            // Obtain all feasible right subtree sets
            vector<TreeNode*> rightTrees = generateTrees(i + 1, end);

            // Select a left subtree from the left subtree set and a right subtree from the right subtree set and splice them to the root node
            for (auto& left : leftTrees) {
                for (auto& right : rightTrees) {
                    TreeNode* currTree = new TreeNode(i);
                    currTree->left = left;
                    currTree->right = right;
                    allTrees.emplace_back(currTree);
                }
            }
        }
        return allTrees;
    }

    vector<TreeNode*> generateTrees(int n) {
        if (!n) {
            return {};
        }
        return generateTrees(1, n);
    }
};

C language code

struct TreeNode** buildTree(int start, int end, int* returnSize) {
    if (start > end) {
        (*returnSize) = 1;
        struct TreeNode** ret = malloc(sizeof(struct TreeNode*));
        ret[0] = NULL;
        return ret;
    }
    *returnSize = 0;
    struct TreeNode** allTrees = malloc(0);
    // Enumerate possible root nodes
    for (int i = start; i <= end; i++) {
        // Obtain all feasible left subtree sets
        int leftTreesSize;
        struct TreeNode** leftTrees = buildTree(start, i - 1, &leftTreesSize);

        // Obtain all feasible right subtree sets
        int rightTreesSize;
        struct TreeNode** rightTrees = buildTree(i + 1, end, &rightTreesSize);

        // Select a left subtree from the left subtree set and a right subtree from the right subtree set and splice them to the root node
        for (int left = 0; left < leftTreesSize; left++) {
            for (int right = 0; right < rightTreesSize; right++) {
                struct TreeNode* currTree = malloc(sizeof(struct TreeNode));
                currTree->val = i;
                currTree->left = leftTrees[left];
                currTree->right = rightTrees[right];

                (*returnSize)++;
                allTrees = realloc(allTrees, sizeof(struct TreeNode*) * (*returnSize));
                allTrees[(*returnSize) - 1] = currTree;
            }
        }
        free(rightTrees);
        free(leftTrees);
    }
    return allTrees;
}

struct TreeNode** generateTrees(int n, int* returnSize) {
    if (!n) {
        (*returnSize) = 0;
        return NULL;
    }
    return buildTree(1, n, returnSize);
}

This code is transferred from: C language code
Java code:

class Solution {
    public List<TreeNode> generateTrees(int n) {
        if (n == 0) {
            return new LinkedList<TreeNode>();
        }
        return generateTrees(1, n);
    }

    public List<TreeNode> generateTrees(int start, int end) {
        List<TreeNode> allTrees = new LinkedList<TreeNode>();
        if (start > end) {
            allTrees.add(null);
            return allTrees;
        }

        // Enumerate possible root nodes
        for (int i = start; i <= end; i++) {
            // Obtain all feasible left subtree sets
            List<TreeNode> leftTrees = generateTrees(start, i - 1);

            // Obtain all feasible right subtree sets
            List<TreeNode> rightTrees = generateTrees(i + 1, end);

            // Select a left subtree from the left subtree set and a right subtree from the right subtree set and splice them to the root node
            for (TreeNode left : leftTrees) {
                for (TreeNode right : rightTrees) {
                    TreeNode currTree = new TreeNode(i);
                    currTree.left = left;
                    currTree.right = right;
                    allTrees.add(currTree);
                }
            }
        }
        return allTrees;
    }
}

This code is transferred from: Java code

summary

As an algorithm, Xiaobai, I can only improve step by step. I hope the starlight will live up to those who have a heart. Something that stays in your mind will someday spring up in your life.
If you find any mistakes in reading, please contact me to make changes. I will thank you very much for giving me the opportunity to learn and face my mistakes.

Tags: Python Java C++ Algorithm leetcode

Posted on Mon, 27 Sep 2021 09:25:07 -0400 by irving