二叉树的前中后序遍历递归写法
树节点
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) { this.val = val; }
}
前序
class Solution {
public List preorderTraversal(TreeNode root) {
List res = new ArrayList<>();
dfs(root, res);
return res;
}
private void dfs(TreeNode node, List res) {
if (node == null) return;
res.add(node.val); // 根
dfs(node.left, res); // 左
dfs(node.right, res); // 右
}
}
中序:
class Solution {
public List inorderTraversal(TreeNode root) {
List res = new ArrayList<>();
dfs(root, res);
return res;
}
private void dfs(TreeNode node, List res) {
if (node == null) return;
dfs(node.left, res); // 左
res.add(node.val); // 根
dfs(node.right, res); // 右
}
}
栈写法:
class Solution {
public List inorderTraversal(TreeNode root) {
List res = new ArrayList<>();
Deque stack = new ArrayDeque<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
// 1. 一直向左走,把所有左边界压入栈
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
// 2. 弹出栈顶(此时是最左的节点)
cur = stack.pop();
res.add(cur.val); // 访问
// 3. 转向右子树(如果有右孩子,下次循环会继续处理右孩子的左边界)
cur = cur.right;
}
return res;
}
}
后序:
class Solution {
public List postorderTraversal(TreeNode root) {
List res = new ArrayList<>();
dfs(root, res);
return res;
}
private void dfs(TreeNode node, List res) {
if (node == null) return;
dfs(node.left, res); // 左
dfs(node.right, res); // 右
res.add(node.val); // 根
}
}
判断是否是二叉搜索树
思路:转化为 中序遍历+是否是递增数组判断
/**
* 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 void dfs(TreeNode node,List res){
if(node==null)return;
dfs(node.left,res);
res.add(node.val);
dfs(node.right,res);
}
public boolean isValidBST(TreeNode root) {
List res=new ArrayList<>();
dfs(root,res);
for(int i=1;i<res.size();i++){
if(res.get(i)<=res.get(i-1))return false;
}
return true;
}
}
1. 数组(Array)
-
取值:
arr[i] -
长度:
arr.length(注意:没有括号,是一个属性)
2. 列表(List / ArrayList / LinkedList)
-
取值:
list.get(i)(⚠️ 这就是你刚才写错的地方) -
长度:
list.size()(注意:有括号,是一个方法)
3. 映射(Map / HashMap)
-
取值:
map.get(key)(它不用数字索引,而是用键去取) -
长度:
map.size()
4. 字符串(String)
-
取某个字符:
str.charAt(i) -
长度:
str.length()
5. 栈(Stack / Deque 作为栈用)
-
取值(只看不取):
stack.peek() -
取值(弹出):
stack.pop()
二叉树展开为链表
给你二叉树的根结点 root ,请你将它展开为一个单链表:
- 展开后的单链表应该同样使用
TreeNode,其中right子指针指向链表中下一个结点,而左子指针始终为null。 - 展开后的单链表应该与二叉树 **先序遍历** 顺序相同。
思路:利用递归进行先序遍历收集为一个列表,对于当前列表,原地修改指针指向
/**
* 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 void dfs(TreeNode node,Listres){
if(node==null)return;
res.add(node);
dfs(node.left,res);
dfs(node.right,res);
}
public void flatten(TreeNode root) {
Listres=new ArrayList<>();
dfs(root,res);
for(int i=1;i<res.size();i++){
TreeNode pre=res.get(i-1);
TreeNode cur=res.get(i);
pre.left=null;
pre.right=cur;
}
}
}
思路2:原地翻转,不开List
-
遍历当前节点
cur。 -
如果
cur.left不为空:-
找到
cur.left这棵树的最右节点,记为pre。 -
将
cur.right挂到pre.right上。 -
将
cur.left移到cur.right上。 -
将
cur.left置为null。
-
-
移动到下一个节点:
cur = cur.right。/**
* 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 void flatten(TreeNode root) {
TreeNode cur=root;
while(cur!=null){
if(cur.left!=null){
TreeNode pre=cur.left;
while(pre.right!=null){
pre=pre.right;
}
pre.right=cur.right;
cur.right=cur.left;
cur.left=null;
}
cur=cur.right;
}
}
}