Preface description
Algorithm learning, daily problem brushing records.
Topic connection
Topic content
Flip a binary tree.
Example:
Input:
Output:
remarks:
This question is inspired by Max Howell's original question:
Google: 90% of our engineers use the software you wrote (Homebrew), but you can't write the question of flipping binary tree on the whiteboard during the interview, which is too bad.
Analysis process
Flipping a binary tree is very simple. You can use recursion.
The binary tree is regarded as the whole of the root node, left child and right child, and the left child and right child of the root node are flipped as a whole.
If the left child and the right child are also trees, the same method is executed recursively until the left child and the right child are empty.
Finally, the root node of the binary tree is returned, which is the inverted binary tree.
Answer code
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public TreeNode invertTree(TreeNode root) { if (root == null) { // If the tree node is empty, it returns null directly return null; } // Using the recursive method, the tree is regarded as the whole of the root node, the left child and the right child, and the left child and the right child of the root node are flipped as a whole. If the left child and the right child are also trees, the same method is executed recursively until the left child and the right child are empty, and the recursion starts backtracking // Gets the left child of the root node TreeNode left = invertTree(root.left); // The left child of the root node is equal to the right child, and the right child is equal to the left child. Flip is realized root.left = invertTree(root.right); root.right = left; // Returns the flipped root node return root; } }
Submit results
The execution time is 0ms, the time beats 100.00% of users, the memory consumption is 35.9MB, and the space beats 37.33% of users.
The original flip binary tree is so simple that I will flip the binary tree. Does Google want me?
Extension analysis
However, I will write the complete code when I brush the questions. Obviously, the above code is not complete. When we execute and run, we input an array and output an array, as shown in the figure:
The invertTree method actually inputs a binary tree TreeNode object, so there is actually an input process of converting an array into a binary tree and an output process of converting a binary tree back to an array. When you brush questions on LeetCode, the LeetCode background has done the conversion for you, but if we want to write the complete code ourselves, we need to do the conversion ourselves.
Here, only one array is given to determine the binary tree, which is proved to be sequence traversal, because pre sequence traversal, middle sequence traversal and post sequence traversal cannot deduce the binary tree from a single array, and sequence traversal can deduce the binary tree from a single array.
Sequence traversal: access all nodes layer by layer from top to bottom, and each layer from left to right.
To facilitate understanding, the following examples are given:
Input array 1: [0,null,2,null,4,null,6]
Output binary tree 1:
Input array 2: [1,null,2,3]
Output binary tree 2:
Input array 3: [0,1,null,null,4]
Output binary tree 3:
Input array 4: [4,2,7,1,3,6,9]
Output binary tree 4:
Array to binary tree: it's a little strange that I have read many algorithm books and consulted many online materials. I rarely see how to turn the sequence traversed array into a binary tree. Next, I have sorted out a conversion method. Please see the complete code arrayToTreeNode method behind to realize breadth first search through queue assistance, That is, simulate the process of sequence traversal from top to bottom and from left to right, and convert the array into a binary tree. Pay attention to the case that the array element is null. When the array element is null, the node has no children, but it will occupy an array element.
Binary tree to array: see the following complete code treenodotoarray method, which also realizes breadth first search through queue assistance, that is, simulate the process from top to bottom and from left to right during sequence traversal, first convert the binary tree into a two-layer List, each layer of the two-layer List saves the node values from left to right of one layer of tree, and finally convert the two-layer List into an array, Here, you should also pay attention to the case that the array elements are null. If all the elements in a row are null, do not use this row; If last element in a row is null, remove last element.
The complete code is as follows:
import java.util.*; public class Main { public static void main(String[] args) { // Get input results Scanner scanner = new Scanner(System.in); String str = scanner.next(); scanner.close(); // Process input results Integer[] nums; if ("[]".equals(str)) { // When the array is empty nums = null; } else { // When the array is not empty String[] strs = str.split("\\[")[1].split("]")[0].split(","); int size = strs.length; nums = new Integer[size]; for (int i = 0; i < size; ++i) { if ("null".equals(strs[i])) { nums[i] = null; } else { nums[i] = Integer.parseInt(strs[i]); } } } // Convert array to binary tree TreeNode root = arrayToTreeNode(nums); // Get output results TreeNode result = invertTree(root); System.out.println(Arrays.toString(treeNodeToArray(result))); } // The array is transformed into a binary tree, the sequence is traversed, and the layers are in the order from top to bottom and from left to right private static TreeNode arrayToTreeNode(Integer[] nums) { // Using queue assistance, you should pay special attention to supporting null array elements. When the array element is null, the node has no children, but it will occupy an array element // If the left child of the node is null and the right child is not null, the next element of the array will start from the child node of the right child, because the left child is null and has no child node // Examples: [0,null,2,null,4,null,6], [1,null,2,3], [0,1,null,null,4], [4,2,7,1,3,6,9] if (nums == null || nums.length == 0) { // If the binary tree node is empty, it returns null directly return null; } // Start subscript of array int i = 1; // First, construct the root node of binary tree TreeNode root = new TreeNode(nums[0]); // Define the current binary tree node and save the temporary value TreeNode current; // Defines the value of the current array Integer value; // Define the queue and create a binary tree Queue<TreeNode> queue = new LinkedList<>(); // First put the root node of the binary tree into the queue, and finally queue.add(root); // Traverse the array and construct a binary tree while (i < nums.length) { // Queue out the first element and get the current binary tree node current = queue.poll(); // Gets the value of the array, with the array subscript plus 1 value = nums[i++]; if (value != null) { // Creates the left child of the current binary tree node TreeNode left = new TreeNode(value); if (current != null) { // Construct the left child of the current binary tree node current.left = left; } // Put the left child of the current binary tree node at the end of the queue queue.add(left); } if (i < nums.length) { // Gets the value of the array, with the array subscript plus 1 value = nums[i++]; if (value != null) { // Creates the right child of the current binary tree node TreeNode right = new TreeNode(value); if (current != null) { // Construct the right child of the current binary tree node current.right = right; } // Put the right child of the current binary tree node at the end of the queue queue.add(right); } } } // Returns the root node of the binary tree return root; } // The binary tree is converted into an array, the sequence is traversed, and the layers are in the order from top to bottom and from left to right. Here, because the binary tree is flipped, special treatment is required. The empty nodes in the last layer should also be displayed and displayed as null, so as to see the effect of the flipped binary tree private static Integer[] treeNodeToArray(TreeNode root) { // Define a two-tier list and save the overall results List<List<Integer>> list = new ArrayList<>(); if (root == null) { // If the binary tree node is empty, an empty array is returned directly return new Integer[0]; } // Through queue assistance, the traversal of each layer is completed from top to bottom. When traversing each layer, each node is traversed, the two child nodes of the node are determined. If it is not empty, the child nodes are placed behind the queue. The queue ensures that the tree traverses from top to bottom according to the hierarchy and each layer traverses from left to right // Define queue Queue<TreeNode> queue = new LinkedList<>(); // First put the root node of the binary tree into the queue, and finally queue.add(root); // Loop until the length of the queue is zero, ending the loop while (queue.size() > 0) { // Define the inner layer list and save the inner layer results List<Integer> temp = new ArrayList<>(); // Gets the length of the queue int size = queue.size(); // Traverse the queue and complete the traversal of one layer of tree nodes each time for (int i = 0; i < size; ++i) { // Queue out first element TreeNode node = queue.poll(); if (node != null) { // Add the value of the listed element to the inner list temp.add(node.val); if (node.left != null) { // Put the left child of the current binary tree node at the end of the queue queue.add(node.left); } else { // If the child node is empty, it should also be put into the queue. Finally, in order to adapt to the effect of flipping the binary tree queue.add(null); } if (node.right != null) { // Put the right child of the current binary tree node at the end of the queue queue.add(node.right); } else { // If the child node is empty, it should also be put into the queue. Finally, in order to adapt to the effect of flipping the binary tree queue.add(null); } } else { // The null value is added to the inner list to adapt to the effect of flipping the binary tree temp.add(null); } } // Are all elements of the inner list empty boolean isAllNull = true; // Judge whether all the elements of the inner list are empty. If all the elements are empty, there is more inner list data in this row for (Integer col : temp) { if (col != null) { // As long as one element is not empty, not all elements are empty isAllNull = false; break; } } if (!isAllNull) { // Not all elements are empty inner lists before they are added to the two-tier list list.add(temp); } } // Print sequence traversal results in two-layer list form System.out.println("treeNodeToArray list:" + list); // Defines the length of the array int count = 0; // Traverse the two-tier list and calculate the length of the array for (List<Integer> row : list) { // The length of each row list is accumulated count += row.size(); } // Define array Integer[] nums = new Integer[count]; // Defines the subscript of the array int n = 0; // Traverse the two-tier list and turn the two-tier list into an array for (List<Integer> row : list) { for (Integer col : row) { nums[n++] = col; } } if (nums[nums.length - 1] == null) { // If the last element is null, delete the last element. In this case, null must fall on the right node, and the last position. If the last element is null, do not keep it. If NULL is on the left, it should be kept return Arrays.copyOf(nums, nums.length - 1); } // Return array return nums; } // Flip binary tree private static TreeNode invertTree(TreeNode root) { if (root == null) { // If the tree node is empty, it returns null directly return null; } // Using the recursive method, the tree is regarded as the whole of the root node, the left child and the right child, and the left child and the right child of the root node are flipped as a whole. If the left child and the right child are also trees, the same method is executed recursively until the left child and the right child are empty, and the recursion starts backtracking // Gets the left child of the root node TreeNode left = invertTree(root.left); // The left child of the root node is equal to the right child, and the right child is equal to the left child. Flip is realized root.left = invertTree(root.right); root.right = left; // Returns the flipped root node return root; } } // Define binary tree class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() { } TreeNode(int val) { this.val = val; } TreeNode(int val, TreeNode left, TreeNode right) { this.val = val; this.left = left; this.right = right; } }
Complete code acquisition: https://github.com/zjhpure/algorithmPractice/blob/master/src/main/java/org/pure/algorithm/invertBinaryTree/Main.java
Original link
Original link: Flip binary tree