introduction

I'm changing jobs recently. Although I'm already an uncle-level programmer, I still need a three-piece set: updating my resume, brushing Boss, and brushing interview questions. This year's market is a bit chilly, and front-end people have to start rolling the algorithm. At present, the difficulty is mainly simple, and a few are medium (more large factories).

In my case, I brushed over thirty leetcodes three years ago, but now it seems that the number is not enough, so I have to pick it up and brush it again this time. Among them, there is a binary tree medium topic. The topic is not difficult, but I think it inspires me a lot, especially in the process of several rounds of analysis. This article will share the process of sorting out my ideas, hoping to inspire everyone.

first round

The first round mainly looks at the topics:

给你n ,求n1n同的二叉How many types of search trees are there? Returns the number of binary search trees that satisfy the meaning of the question.

The first thing is the reading comprehension of the topic. I didn't do many questions, and the concept of binary search tree became a bit vague after a long time. Let's start with the explanation of the concept: A binary search tree is a binary tree whose left subtree is smaller than the root and whose right subtree is larger than the root . Combined with the example, it is easy to understand the meaning of the title: how many kinds of binary search trees can be sorted out for a given number sequence 1-n .

Then I analyzed how to solve the problem, that is, to find a way to calculate the number of permutations. I quickly thought of the permutations and combinations in mathematics. The permutations and combinations can be converted into formulas. For example, 10 elementary school students line up. can be converted to the factorial of Equation 10.

However, the arrangement of the binary search tree is not the same. There are n kinds of root nodes, but there are several kinds of arrangements further down. How to calculate? A little clueless, thinking for a few minutes, can not find the pattern. I kind of want to flip the answer...

second round

The second round is to organize the key ideas. When I encountered difficulties in the first round, I almost went through the answers, and then I was held down by myself, and I calmed down to organize my ideas again.

The direction of thinking is how to find the law of arrangement from the details of the topic. The first thing that comes to mind is the binary search tree. Let’s take a good look at its concept: the left side is smaller than the root, and the right side is larger than the root , which is not the same as the ordered array. Similarly, after selecting an array element as the root, the number on the left is the left subtree, and the number on the right is the right subtree. In fact, an array is used to represent a binary tree. In the data structure, it has been forgotten for too long.

For example (sometimes it is easier to understand by thinking with examples), given n=5 , using 2 as the root of the tree, then the left subtree is 1, and the right subtree is 3-5, 1 1 sort. What about 3-5 of the right subtree, how to arrange it? Seems to be stuck again.

The key breakthrough is coming. Since it is an ordered array, is the arrangement of 3-5 the same as 1-3? Subtracting 2 uniformly does not affect the sorting order, so the number of sorting is the same!

Well, no matter what the number is, we can abstract it into a 1-n permutation! We can use iteration to solve the problem.

After the abstraction is: given a sequence of numbers ---1bfd4a6e574a09e0a22e91a4b295fbf6 1-n , when a number k(1≤k≤n) is selected as the root, f(k) = f(k-1) * f(n-k) . f(1), f(2) can be given directly.

The first version of the code came. After finding the rule, I didn't write a few lines of code, and it passed immediately after submitting it.

 var numTrees = function(n) {
    // 注意:n=0 时,需要处理为 1,因为 n=0 表示没有子节点,也是一种排列。
    if (n < 3) return n || 1

    let nums = 0
    for (let i=1; i<=n; i++) {
        nums += numTrees(i-1) * numTrees(n-i)
    }

    return nums
};

third round

The third round was optimization, and the second round of thinking led me to finally find out how to solve the problem, which also gave me a lot of confidence and inspiration, but the complexity was relatively high and there was a lot of room for optimization.

The optimization idea is also to start with the arrangement of 3-5 and 1-3. It is easy to find that: after the array is more than half, the number of arrangements in the second half of the array is actually the same as the first half! That is, there is no need to calculate the second half, just double the first half. The only thing to consider is that the length of the array should be divided into odd and even numbers.

The code is also very simple, paste it directly for reference.

 var numTrees = function(n) {
    if (n < 3) return n || 1

    let nums = 0
    let mid = Math.ceil(n / 2)

    let i
    for (i=1; i<mid; i++) {
        nums += numTrees(i-1) * numTrees(n-i)
    }
    // 数据长度分奇偶处理
    if (n&1) {
        nums = nums * 2 + numTrees(i-1) * numTrees(n-i)
    } else {
        nums = (nums + numTrees(i-1) * numTrees(n-i)) * 2
    }

    return nums
};

Summarize

When difficulties arise, be patient, start with the details, and look for general patterns.


xie_zhichao
1.1k 声望274 粉丝

Web全栈开发者。