二叉树练习题集合

遇到的问题,(不知道为什么)

  1. 字符串列表—to—字符串数组
    需要加大小;
(String[])(curpre1.toArray(new String[curpre1.size()]));
  1. 字符串数组部分转列表
    大小不可变
List<String> curin2 = asList(copyOfRange(str2,i+1,str2.length));

remeber

List的大小用size();
char[] 的大小是length();
string的大小是length();

遍历问题

  1. 通过前序和中序的信息来获得
    1)原二叉树
    2)后序遍历
    可以通过递归来处理:
    首先找到根节点,然后通过根节点将二叉树分为左子树与右子树,然后再根据二叉树遍历的规则来往数组中添加节点或者连接。

例1:

给定一个二叉树的前序遍历和中序遍历的序列,输出对应这个二叉树的后续遍历序列。
输入
ABDEC DBEAC
输出
DEBCA

import java.util.*;
import static java.util.Arrays.*;
public class Main{
    public static void main(String[] agrs){
        Scanner in = new Scanner(System.in);
        String str1 = in.next();
        String str2 = in.next();
        char[] char1 = str1.toCharArray();
        char[] char2 = str2.toCharArray();
        System.out.println(Main.findback(char1,char2));
    }
    
    public static String findback(char []str1, char []str2){
        StringBuffer root = new StringBuffer();
        for(int i = 0 ; i < str2.length; i++){
            if(str2[i]==str1[0]){
                root.append(findback(copyOfRange(str1, 1, i+1),copyOfRange(str2, 0, i)));
                root.append(findback(copyOfRange(str1, i+1, str1.length),copyOfRange(str2, i+1, str2.length)));
                root.append(str1[0]);
                break;
            }
        }
        return root.toString();
    }
}

例2:

题目描述
给满出二叉树,编写算法将其转化为求和树

什么是求和树:二叉树的求和树, 是一颗同样结构的二叉树,其树中的每个节点将包含原始树中的左子树和右子树的和。

二叉树:
10
/
-2 6
/ \ / \
8 -4 7 5

求和树:
20(4-2+12+6)
/
4(8-4) 12(7+5)
/ \ / \
0 0 0 0

二叉树给出前序和中序输入,求和树要求中序输出;
所有处理数据不会大于int;

笨笨的处理方法,没有看到是满二叉树,前序只是一个迷惑行为。
重构了整个二叉树,并且还修改了二叉树的结构,用于保存上一个值的信息。
看了大佬的思想,发现了可以用一个数组通过二分法直接就维护了,因为是满二叉树,因此只需要中序遍历便可以得到原来的树结构,通过一个数组来存储求和(不算本节点的值)的结果,然后递归得到答案;

import java.util.*;

import static java.lang.Integer.valueOf;
import static java.util.Arrays.*;
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        String[] str1 = in.nextLine().split(" ");
        String[] str2 = in.nextLine().split(" ");
        TreeNode root = getBinaryTree(str1, str2);
        inSelect(root);
    }

    public static TreeNode getBinaryTree(String[] str1,String[] str2){
        if(str1.length==0||str2.length==0){
            return new TreeNode(0,0);
        }
        TreeNode nodeRoot = new TreeNode(valueOf(str1[0]),valueOf(str1[0]));
        for(int i = 0 ;i < str2.length; i++){
            if(str1[0].equals(str2[i])){
                nodeRoot.leftNode = getBinaryTree(copyOfRange(str1, 1, i+1),copyOfRange(str2, 0, i));
                nodeRoot.rightNode = getBinaryTree(copyOfRange(str1, i + 1, str1.length),copyOfRange(str2, i+1, str2.length));
                nodeRoot.val =  nodeRoot.leftNode.val + nodeRoot.rightNode.val + nodeRoot.rightNode.oldval + nodeRoot.leftNode.oldval;
                break;
            }
        }
        return nodeRoot;
    }

    public static void inSelect(TreeNode root){
        if(root.leftNode!=null){
            inSelect(root.leftNode);
            System.out.print(root.val+" ");
            inSelect(root.rightNode);
        }
    }

    public static class TreeNode{
        int val;
        int oldval;
        TreeNode leftNode;
        TreeNode rightNode;
        TreeNode (int val,int oldval){
            this.val = val;
            this.oldval = oldval;
            leftNode = null;
            rightNode = null;
        }
    }
}

大佬的思想:

注意临界数据,也就是最后一层0值的节点

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
 
void sumtree(vector<int> &inorder, int left, int right){
    int mid = (left + right)/2;
    if(mid == left){
        inorder[mid] = 0;
        return;
    }
    inorder[mid] = accumulate(inorder.begin()+left, inorder.begin()+right, -inorder[mid]);
    sumtree(inorder, left, mid);
    sumtree(inorder, mid+1, right);
}
 
int main(void){
    string line;
    getline(cin, line);
    istringstream pre_stream(line);
    vector<int> preorder((istream_iterator<int>(pre_stream)), istream_iterator<int>());
    getline(cin, line);
    istringstream in_stream(line);
    vector<int> inorder((istream_iterator<int>(in_stream)), istream_iterator<int>());
    sumtree(inorder, 0, inorder.size());
    copy(inorder.begin(), inorder.end(),ostream_iterator<int>(cout, " "));
    cout<<endl;
    return 0;
}

例3:

二叉搜索树的判定

最大最小值:分类判断
中序遍历:

  1. 采用递归
  2. 采用栈
class Solution {
  public boolean helper(TreeNode node, Integer lower, Integer upper) {
    if (node == null) return true;

    int val = node.val;
    if (lower != null && val <= lower) return false;
    if (upper != null && val >= upper) return false;

    if (! helper(node.right, val, upper)) return false;
    if (! helper(node.left, lower, val)) return false;
    return true;
  }

  public boolean isValidBST(TreeNode root) {
    return helper(root, null, null);
  }
}
public boolean isValidBST(TreeNode root) {
        return validate(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    public boolean validate(TreeNode node, long min, long max) {
        if (node == null) {
            return true;
        }
        if (node.val <= min || node.val >= max) {
            return false;
        }
        return  validate(node.left, min, node.val) && validate(node.right, node.val, max);
    }
class Solution {
  public boolean isValidBST(TreeNode root) {
    Stack<TreeNode> stack = new Stack();
    double inorder = - Double.MAX_VALUE;

    while (!stack.isEmpty() || root != null) {
      while (root != null) {
        stack.push(root);
        root = root.left;
      }
      root = stack.pop();
      // 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树
      if (root.val <= inorder) return false;
      inorder = root.val;
      root = root.right;
    }
    return true;
  }
}

你可能感兴趣的:(java)