Analysis of the idea of the sword point of Offer interview questions

Interview Question 58: Next Node in a Binary Tree

Given a binary tree and a node in it, find the next node in inorder traversal order and return. Note that nodes in the tree contain not only left and right child nodes, but also pointers to parent nodes.
Idea analysis:
1. If the binary tree is empty, return empty
2. If the right subtree of the binary tree is not empty, then return the leftmost child node
of the right subtree 3. If the right subtree of the binary tree is empty, then find the first one The node is the node of the left child of the parent node, and returns its parent node, which is the next node of the current node.

public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        if(pNode == null)
            return pNode;
        if(pNode.right != null){
            TreeLinkNode curr = pNode.right;
            while(curr != null && curr.left!= null){
                curr = curr.left;
            }
            return curr;
        }else{
            TreeLinkNode curr = pNode;
            while(curr.next != null){
                if(curr.next.left == curr)
                    return curr.next;
                curr = curr.next;
            }
        }
        return null;
    }

Interview Question 59: Symmetric Binary Tree

Please implement a function to determine whether a binary tree is symmetric. Note that a binary tree is defined as symmetric if it is the same as its mirror image.
Idea analysis:
For binary tree traversal, a symmetrical traversal algorithm is defined for preorder traversal, that is, traverse the parent node first, then traverse its right child node, and finally traverse its left child node.
If the binary tree is symmetric, the result of the preorder traversal is consistent with the result obtained by our custom traversal algorithm.
That is, the left subtree of the left subtree is the same as the right subtree of the right subtree, and the right subtree of the left subtree is the same as the left subtree of the right subtree!
Note: It is necessary to take into account the empty nodes, otherwise if all nodes of a tree have the same value, but are not symmetrical, only the empty nodes can be distinguished

Recursive implementation:

 boolean isSymmetrical(TreeNode pRoot)
    {
        if(pRoot == null)
            return true;
        return symmetricalCore(pRoot,pRoot);
    }
    boolean symmetricalCore(TreeNode p1,TreeNode p2){
    //都为空节点,
        if(p1 == null && p2 == null)
            return true;
        if(p1 == null || p2 == null)
            return false;
        if(p1.val != p2.val)
            return false;
        return symmetricalCore(p1.left,p2.right) && symmetricalCore(p1.right,p2.left);
    }

Non-recursive implementation:
It needs to be implemented with the help of two stacks, which store the nodes of the right subtree and the left subtree respectively. The left subtree is pushed into the left and right child nodes of the stack, and the right subtree is pushed into the right and left child nodes of the stack, and then popped out of the stack in turn Determine whether the nodes are the same

boolean isSymmetrical(TreeNode pRoot){
        if(pRoot == null)
            return true;
        Stack<TreeNode> s1 = new Stack<>();
        Stack<TreeNode> s2 = new Stack<>();
        s1.push(pRoot.left);
        s2.push(pRoot.right);
        while(!s1.empty() && !s2.empty()){
            TreeNode left = s1.pop();
            TreeNode right = s2.pop();
            if(left == null && right == null)
                continue;
            if(left == null || right == null)
                return false;
            if(left.val == right.val){
                s1.push(left.left);
                s1.push(left.right);
                s2.push(right.right);
                s2.push(right.left);
            }else{
                return false;
            }
        }
        return true;
    }

Interview Question 62: Printing a Binary Tree in Zigzag Order

Please implement a function to print the binary tree in a zigzag pattern, that is, the first line is printed in left-to-right order, the second layer is printed in right-to-left order, the third line is printed in left-to-right order, and the other lines are printed in order from left to right. And so on.
Idea analysis:
odd-numbered layers print nodes from left to right, even-numbered layers print nodes from right to left, and the order of nodes printed on odd-numbered layers and even-numbered layers is inconsistent, so we need two stacks to store the nodes of odd-numbered layers and Nodes of even layers.
The difference in the printing order lies in the order in which the nodes are pushed onto the stack. The left and right nodes of the odd-numbered layer are pushed onto the stack, and the even-numbered layer is pushed to the right and left nodes of the stack. Therefore, a variable is needed to record which layer of the tree is currently, so as to determine whether it is an odd or even layer.

import java.util.ArrayList;
import java.util.Stack;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        //保存奇数层节点
        Stack<TreeNode> s1 = new Stack<>();
        //保存偶数层节点
        Stack<TreeNode> s2 = new Stack<>();
        ArrayList<Integer> curr;
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if(pRoot == null)
            return result;
        int level = 1;
        s1.push(pRoot);
        while(!s1.empty() || !s2.empty()){
            curr = new ArrayList<>();
            if(level % 2 == 1){
                while(!s1.empty()){
                    TreeNode pNode = s1.pop();
                    curr.add(pNode.val);
                    if(pNode.left != null)
                        s2.push(pNode.left);
                    if(pNode.right != null)
                        s2.push(pNode.right);
                }
                if(!curr.isEmpty()){
                    level++;
                    result.add(curr);
                }
            }else{
                while(!s2.empty()){
                    TreeNode pNode = s2.pop();
                    curr.add(pNode.val);
                    if(pNode.right != null)
                        s1.push(pNode.right);
                    if(pNode.left != null)
                        s1.push(pNode.left);
                }
                if(!curr.isEmpty()){
                    level++;
                    result.add(curr);
                }
            }
        }
        return result;
    }
}

Interview question 60: Printing a binary tree over multiple lines

Print the binary tree layer by layer from top to bottom, and the nodes in the same layer are output from left to right. Each layer outputs one line.
Idea:
Printing by layers requires a queue to save nodes, and each layer outputs a line, so it is necessary to record the number of nodes of the current printing layer, and the number of nodes of the current printing layer is -1 every time the column is out. When entering the queue, we can Calculate the number of nodes in the next layer.

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if(pRoot == null)
            return result;
        Queue<TreeNode> s = new LinkedList<>();
        int currLevel = 1;
        int nextLevel = 0;
        s.offer(pRoot);
        ArrayList<Integer> curr = new ArrayList<>();
        while(!s.isEmpty()){
            TreeNode pNode = s.poll();
            currLevel--;
            curr.add(pNode.val);
            if(pNode.left != null){
                s.offer(pNode.left);
                nextLevel++;
            }
            if(pNode.right != null){
                s.offer(pNode.right);
                nextLevel++;
            }
            if(currLevel == 0){
                result.add(curr);
                curr = new ArrayList<>();
                currLevel = nextLevel;
                nextLevel = 0;
            }
        }
        return result;
    }

}

Recursive implementation:

public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        depth(pRoot, 1, list);
        return list;
    }
    //打印下一层的左右孩子节点
    private void depth(TreeNode root, int depth, ArrayList<ArrayList<Integer>> list) {
        if(root == null) return;
        if(depth > list.size())
            list.add(new ArrayList<Integer>());
        list.get(depth -1).add(root.val);

        depth(root.left, depth + 1, list);
        depth(root.right, depth + 1, list);
    }
}

Interview Question 62: Serializing a Binary Tree

Please implement two functions to serialize and deserialize the binary tree respectively. Analysis of
ideas
: Normally, we need to know the preorder traversal, inorder traversal or inorder traversal, and the subsequent traversal can build the binary tree, but here, if we put The empty nodes are also saved, then we can construct a binary tree from this sequence containing empty nodes.
Here use preorder traversal

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    String Serialize(TreeNode root) {
        StringBuffer sb = new StringBuffer();
        if(root == null){
            sb.append("#,");
            return sb.toString();
        }
        sb.append(root.val+",");
        sb.append(Serialize(root.left));
        sb.append(Serialize(root.right));
        return sb.toString();
    }
    private int index =  -1;
    TreeNode Deserialize(String str) {
        index ++;
        String[] strs = str.split(",");
        TreeNode node = null;
        if(!strs[index].equals("#")){
            node = new TreeNode(Integer.parseInt(strs[index]));
            node.left = Deserialize(str);
            node.right = Deserialize(str);
        }
        return node;
    }
}

Interview Question 63: The Kth Node of a Binary Search Tree

Given a binary search tree, find the kth largest node in it. For example, in 5 / \ 3 7 /\ /\ 2 4 6 8, the value of the third node in the numerical order of the nodes is 4.
Idea:
In order to traverse a binary tree, an ordered sequence can be obtained. All in-order traversal of the binary tree, the K-th largest node is the node of the K-th visit, which can be implemented recursively or non-recursively.

import java.util.*;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    //非递归实现,借助栈来实现
    TreeNode KthNode(TreeNode pRoot, int k){
        int index = 0;
        Stack<TreeNode> s = new Stack<>();
        if(pRoot == null)
            return pRoot;
        while(pRoot != null || !s.empty()){
            while(pRoot != null){
                s.push(pRoot);
                pRoot = pRoot.left;
            }
            if(!s.empty()){
                TreeNode p = s.pop();
                index++;
                if(index == k)
                    return p;
                pRoot = p.right;
            }
        }
        return null;
    }
    //递归实现
    private int index = 0;
    TreeNode KthNode(TreeNode pRoot, int k)
    {
        if(pRoot != null){
            TreeNode p1 = KthNode(pRoot.left,k);
            if(p1 != null)
                return p1;
            index ++;
            if(index == k)
                return pRoot;
            TreeNode p2 = KthNode(pRoot.right,k);
            if(p2 != null)
                return p2;
        }
        return null;
    }
}

Interview Question 64: Median in Data Streams

How to get the median in a data stream? If an odd number of values ​​is read from the data stream, then the median is the value in the middle after all the values ​​are sorted. If an even number of values ​​is read from the data stream, then the median is the average of the two middle numbers after all the values ​​are sorted.
Idea analysis:
In order to ensure the time efficiency of inserting new data and taking the median is efficient, here we use a container with a large top heap + a small top heap, and satisfy:
1. The difference in the number of data in the two heaps cannot exceed 1, which can Make the median only appear at the junction of the two heaps;
2. All the data in the large top heap is smaller than the small top heap, so that the sorting requirements are met.

//Java的PriorityQueue 是从JDK1.5开始提供的新的数据结构接口
//默认内部是自然排序,结果为小顶堆
//可以自定义排序器,比如下面反转比较,完成大顶堆。
import java.util.*;
public class Solution {
    int count = 0;
    PriorityQueue<Integer> minHeap = new PriorityQueue<>();
    PriorityQueue<Integer> maxHeap = new PriorityQueue<>(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            //默认最小堆
            return o2.compareTo(o1);
        }
    });
    public void Insert(Integer num) {
        count++;
        if((count & 1) == 0){   //偶数
            if(!maxHeap.isEmpty() && num < maxHeap.peek()){
                maxHeap.offer(num);
                num = maxHeap.poll();
            }
            minHeap.offer(num);
        }else{
            if(!minHeap.isEmpty() && num > minHeap.peek()){
                minHeap.offer(num);
                num = minHeap.poll();
            }
            maxHeap.offer(num);
        }

    }

    public Double GetMedian() {
        double result = 0.0;
        if((count & 1) == 1){
            result = (double) maxHeap.peek();
        }else{
            result = (maxHeap.peek()+minHeap.peek())/2.0;
        }
        return result;
    }
}

Interview Question 65: Maximum Sliding Window

Given an array and the size of the sliding window, find the maximum value of all values ​​in the sliding window. For example, if the input array is {2,3,4,2,6,2,5,1} and the size of the sliding window is 3, then there are 6 sliding windows in total, and their maximum values ​​are {4,4,6, 6,6,5}; There are six sliding windows for the array {2,3,4,2,6,2,5,1}: {[2,3,4],2,6,2,5 ,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4 ,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5, 1]}.
Idea analysis:
The sliding window should be a queue, but in order to get the maximum value of the sliding window, the queue sequence can delete elements from both ends, so a double-ended queue is used. The queue stores the index position of the element in the array rather than the element itself!
Principle: For the newly arrived element k, compare it with the elements in the deque
1) The front is smaller than k, and it is directly removed from the queue (because it is no longer possible to be the maximum value of the sliding window behind!),
2) The front For X larger than k, compare the subscripts of the two to determine whether X is no longer in the window. If it is no longer, it is directly removed from the queue.
Among them , the first element of the queue is the maximum value in the sliding window.

import java.util.*;
public class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size)
    {
        LinkedList<Integer> q = new LinkedList<Integer>();
        ArrayList<Integer> result = new ArrayList<>();
        if(num == null || size > num.length || size <= 0)
            return result;
        for(int i=0;i<size-1;i++){
            while(!q.isEmpty() && num[i] > num[q.getLast()]){
                q.removeLast();
            }
            q.addLast(i);
        }
        for(int i=size-1;i<num.length;i++){
            while(!q.isEmpty() && num[i] > num[q.getLast()]){
                q.removeLast();
            }
            q.addLast(i);
            if(i - q.getFirst()+1 >size)
                q.removeFirst();
            result.add(num[q.getFirst()]);
        }
        return result;
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324536123&siteId=291194637
Recommended