前序、中序、后序的递归解法非常好做,但是迭代的写法比较生疏,甚至可以写上一个多小时,令人害怕
BST的题目做得不是很好,感觉主要问题是脑子想不到递归该如何去解,思维混乱
序列化和反序列化这类的题目也比较生疏,虽然LeetCode上把它标为hard,但是感觉还是很常见的题目之一,一定要会做
非递归前序遍历
前序遍历其实是根左右
非递归前序遍历的思路:如果先输出遍历元素,再向栈中压入右节点,左节点,这就是前序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
stack.add(root);
List<Integer> res = new ArrayList<>();
while(!stack.isEmpty()){
root = stack.pop();
if(root == null) continue;
res.add(root.val);
stack.add(root.right);
stack.add(root.left);
}
return res;
}
}
非递归中序遍历
中序遍历是 左根右
当时写了一个小时才AC,太弱了
其实思路缕清以后发现,也不难
思路在此,只要root != null,那就将root一直压入栈中,root = root.left 如果root == null了,那就说明最左边的元素已经到头了,这个时候就从栈中弹出节点,打印这个节点,然后让root = root.right 一直循环操作,直到栈为空了
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> res = new ArrayList<>();
while(root != null || !stack.isEmpty()) {
if(root != null){
stack.add(root);
root = root.left;
}else{
root = stack.pop();
res.add(root.val);
root = root.right;
}
}
return res;
}
}
非递归后序遍历
后序是 左右根
反过来是 根右左
所以就是在前序遍历的基础上,改动一下,再进行逆序即可
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
stack.add(root);
List<Integer> res = new ArrayList<>();
while(!stack.isEmpty()){
root = stack.pop();
if(root == null) continue;
res.add(root.val);
stack.add(root.left);
stack.add(root.right);
}
Collections.reverse(res);
return res;
}
}
LeetCode669.修建二叉搜索树
LeetCode669
这道题当时并没有做出来,思路比较混乱,甚至没有思路
看了题解才做出来,觉得递归真是绝呀
思路在此:
1.如果node.val <L,那么说明node的左子树也全部小于L,只需要考虑node的右子树部分就行了
2.如果node.val > R,那么说明node的右子树也全部大于R,只需要考虑node的右子树部分就行了
3.如果node.val在[L,R]之间,那么就需要对左右子树同时进行修剪
我怎么就想不到呢[愤恨]
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode trimBST(TreeNode root, int L, int R) {
if(root == null) return null;
if(root.val > R) return trimBST(root.left,L,R);
if(root.val < L) return trimBST(root.right,L,R);
root.left = trimBST(root.left,L,R);
root.right = trimBST(root.right,L,R);
return root;
}
}
二叉搜索树的序列化、反序列化
不需要"null"或者"#"这些占位符,使用前序遍历、后序遍历的序列,就可以确定二叉搜索树了
对于普通的二叉树需要有这种占位符的字符串序列 或者 前序+中序 或者 后序+中序 才可以确定,因为二叉搜索树本身的中序就是知道的,所以BST只需要前序或后序遍历即可确定。
前序遍历解法
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
//编码的字符串尽可能紧凑,也就是说不需要"null"或者"#"这些占位符
//通过一串数字就可以确定这个二叉树的模样,因为它是二叉搜索树呀
//普通的二叉树需要有这种占位符的字符串或者前序+中序序列才可以确定
/*--- 前序遍历的解法 ---*/
if(root == null){
return "";
}
String str = String.valueOf(root.val)+",";
str += serialize(root.left);
str += serialize(root.right);
return str;
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data.length() < 1){
return null;
}
String[] str = data.split(",");
return deserialize(new TreeNode(0),str,0,str.length);
}
public TreeNode deserialize(TreeNode root,String[] data,int s,int e){
if(s < e ){
root = new TreeNode(Integer.valueOf(data[s]));
int i = s + 1;
int n2 = Integer.valueOf(data[s]);
for(i = s+1;i < e;i++){
int n1 = Integer.valueOf(data[i]);
if(n1 > n2){
break;
}
}
root.left = deserialize(root.left,data,s+1,i);
root.right = deserialize(root.right,data,i,e);
return root;
}
return null;
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));
普通二叉树的序列化、反序列化
前序遍历
使用有占位符的字符串
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
//前序遍历
if(root == null) return "null";
String str = String.valueOf(root.val)+",";
str += serialize(root.left)+",";
str += serialize(root.right);
return str;
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data){
String[] str = data.split(",");
return mydeserialize(str,new TreeNode(0));
}
int point = 0;
public TreeNode mydeserialize(String[] data,TreeNode node) {
if(data[point].equals("null") || point >= data.length){
point++;
return null;
}
node = new TreeNode(Integer.valueOf(data[point++]));
node.left = mydeserialize(data,node.left);
node.right = mydeserialize(data,node.right);
return node;
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));
层次遍历
这里要使用StringBuilder,可以提升很大的效率
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
//层次遍历
if(root == null){
return "";
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
StringBuilder res = new StringBuilder("");
while(!queue.isEmpty()){
root = queue.poll();
if(root == null){
res.append("null,");
}else{
res.append(root.val + ",");
queue.add(root.left);
queue.add(root.right);
}
}
//System.out.println(res);
return res.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data.length() < 1){
return null;
}
String[] str = data.split(",");
Queue<TreeNode> queue = new LinkedList<>();
TreeNode root = new TreeNode(Integer.valueOf(str[0]));
queue.add(root);
int i = 1;
while(i < str.length && !queue.isEmpty()){
TreeNode knode = queue.poll();
if(str[i].equals("null")){
knode.left = null;
i++;
}else{
knode.left = new TreeNode(Integer.valueOf(str[i++]));
queue.add(knode.left);
}
if(str[i].equals("null")){
knode.right = null;
i++;
}else{
knode.right = new TreeNode(Integer.valueOf(str[i++]));
queue.add(knode.right);
}
}
return root;
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));