Leetcode problem solving series -- symmetric binary tree (recursion)

Posted by godwisam on Thu, 27 Jan 2022 15:12:33 +0100

This topic aims to share some interesting or valuable topics found in the process of brushing Leecode. [answer based on js, of course].

Recursive algorithm has always been one of the key types of leetcode medium difficulty exercises, so the key is self-evident.

Topic related

    1
   / \
  2   2
 / \ / \
3  4 4  3

However, the following [1,2,2,null,3,null,3] is not mirror symmetric:

    1
   / \
  2   2
   \   \
   3    3

Tips

Considering that some students may not use js to brush leetcode, let's briefly introduce the data input of tree type in JS. As shown in the above question, the input of a given binary tree is not an array, but should be as follows: each node is an object:

 const root = {
      val: 3,
      left: { // Left indicates the left child node of the current node
        val: 9,
        left: null, // As can be seen from the above figure, node 9 has no left and right child nodes
        right: null,
      },
      right: {
        val: 20,
        left: {
          val: 15, // As can be seen from the above figure, node 15 has no left and right child nodes
          left: null, 
          right: null,
        }, 
        right: {
          val: 7, // As can be seen from the above figure, node 7 has no left and right child nodes
          left: null, 
          right: null,
        },
      }
    }

Train of thought analysis

First of all, this problem is an obvious recursive problem, and the problem of recursive classification is generally the following steps:

  1. Extract the logic of the recursive part
  2. Judge boundary conditions

  • First of all, in terms of overall logic, if you want to determine that a tree is a mirror binary tree, you must start from the left and right nodes of the root node. Each group of nodes encountered in the traversal process (represented by L and R) must meet that the left node of L = the right node of R, and the right node of L = the left node of R. because it will be compared recursively, it is equal here. In fact, as long as the val value is equal:
  • The second is to consider the boundary conditions

    1. If the initial is an empty tree, it returns the result directly, which is also symmetrical;
    2. During synchronous comparison, in any step, as long as the left node that does not meet L = the right node of R and the right node of L = the left node of R, it ends in advance and returns false;
    3. If the comparison can end on both sides at the same time, it indicates that it is a symmetric tree and returns true;

Then, as mentioned above, write the logic of the recursive part first:

    var recuCompare = function (L, R) {
        if(!L && !R) { // It means that the comparison ends at the same time or there is no child node on both sides
            return true;
        }
        if(!L || !R || L.val !== R.val ) { // Deduct the first case, then! L or! R indicates that the left and right ends at the same time, that is, there is asymmetry
            return false;
        }
        return recuCompare(L.left, R.right) && recuCompare(L.right, R.left); // Continue to compare down
    }

Then add the recursive starting condition part, and the complete code can be obtained.

Complete code

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isSymmetric = function(root) {
    if(!root) {return true};
    return recuCompare(root.left, root.right)
};
var recuCompare = function (L, R) {
    if(!L && !R) {
        return true;
    }
    if(!L || !R || L.val !== R.val )  {
        return false;
    }
    return recuCompare(L.left, R.right) && recuCompare(L.right, R.left);
}

Have you found that recursive problems are not long after the code is written, but it is difficult to understand, so you need to try to grasp the logical focus.

It is recommended that you write your own code and run after reading it
It is recommended that you write your own code and run after reading it
It is recommended that you write your own code and run after reading it

Because the writing method and details of many boundary conditions are actually the most common bugs in the debugging process.

In addition, you can use the idea of this topic to try to solve the problem of recursive backtracking - the substructure of the tree, so as to consolidate what you have learned https://leetcode-cn.com/probl...

So, a simple problem is solved again!

Topics: Javascript Algorithm leetcode recursion