leecode更新
This commit is contained in:
parent
a768b112ca
commit
88bbded9ca
|
|
@ -4,7 +4,7 @@ package com.markilue.leecode.tree;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static com.markilue.leecode.tree.InorderTraversal.inorderTraversal1;
|
||||
import static com.markilue.leecode.tree.T03_InorderTraversal.inorderTraversal1;
|
||||
|
||||
/**
|
||||
* 删除二叉排序树的某个节点
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import org.junit.Test;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static com.markilue.leecode.tree.InorderTraversal.inorderTraversal1;
|
||||
import static com.markilue.leecode.tree.T03_InorderTraversal.inorderTraversal1;
|
||||
|
||||
/**
|
||||
* @BelongsProject: Leecode
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import java.util.*;
|
|||
* 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class PostOrderTraversal {
|
||||
public class T02_PostOrderTraversal {
|
||||
|
||||
|
||||
@Test
|
||||
|
|
@ -8,7 +8,7 @@ import java.util.Stack;
|
|||
/**
|
||||
* 中序遍历二叉排序树
|
||||
*/
|
||||
public class InorderTraversal {
|
||||
public class T03_InorderTraversal {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ import java.util.*;
|
|||
* 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class LevelOrder {
|
||||
public class T04_LevelOrder {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
|
@ -2,11 +2,9 @@ package com.markilue.leecode.tree;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import static com.markilue.leecode.tree.InorderTraversal.inorderTraversal1;
|
||||
import static com.markilue.leecode.tree.T03_InorderTraversal.inorderTraversal1;
|
||||
|
||||
/**
|
||||
* @BelongsProject: Leecode
|
||||
|
|
|
|||
|
|
@ -0,0 +1,220 @@
|
|||
package com.markilue.leecode.tree.second;
|
||||
|
||||
import com.markilue.leecode.tree.TreeNode;
|
||||
import com.markilue.leecode.tree.TreeUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.tree.second
|
||||
*@Author: dingjiawen
|
||||
*@CreateTime: 2023-01-05 10:25
|
||||
*@Description:
|
||||
* TODO 二刷leecode145题 二叉树的后序遍历:
|
||||
* 给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T02_PostOrderTraversal {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(3,1,2,5,6,7,8,10));
|
||||
TreeNode root = TreeUtils.structureTree(list, 0);
|
||||
System.out.println(postorderTraversal3(root));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 思路:递归法
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
List<Integer> result;
|
||||
public List<Integer> postorderTraversal(TreeNode root) {
|
||||
result=new ArrayList<>();
|
||||
postTraversal(root);
|
||||
return result;
|
||||
|
||||
}
|
||||
public void postTraversal(TreeNode root) {
|
||||
if(root==null){
|
||||
return;
|
||||
}
|
||||
|
||||
postTraversal(root.left);
|
||||
postTraversal(root.right);
|
||||
result.add(root.val);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 思路:stack迭代法:中右左——>反序:左右中
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public List<Integer> postorderTraversal1(TreeNode root) {
|
||||
List<Integer> result = new ArrayList<>();
|
||||
|
||||
if(root==null){
|
||||
return result;
|
||||
}
|
||||
|
||||
Stack<TreeNode> stack = new Stack<>();
|
||||
stack.push(root);
|
||||
|
||||
while(!stack.isEmpty()){
|
||||
|
||||
TreeNode node = stack.pop();
|
||||
result.add(node.val);
|
||||
if(node.left!=null){
|
||||
stack.push(node.left);
|
||||
}
|
||||
if(node.right!=null){
|
||||
stack.push(node.right);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int size = result.size();
|
||||
List<Integer> result1 = new ArrayList<>();
|
||||
while (size>0){
|
||||
result1.add(result.get(--size));
|
||||
}
|
||||
return result1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 思路:优化stack迭代法:改变树结构
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public List<Integer> postorderTraversal2(TreeNode root) {
|
||||
List<Integer> result = new ArrayList<>();
|
||||
|
||||
if(root==null){
|
||||
return result;
|
||||
}
|
||||
|
||||
Stack<TreeNode> stack = new Stack<>();
|
||||
TreeNode cur=root;
|
||||
|
||||
while(cur!=null||!stack.isEmpty()){
|
||||
|
||||
if(cur!=null){
|
||||
stack.push(cur);
|
||||
cur=cur.left;
|
||||
}else {
|
||||
TreeNode node = stack.peek();
|
||||
if(node.right!=null){
|
||||
cur=node.right;
|
||||
node.right=null;//核心是把right置空,防止下次在遍历到,但是会改变原本的树结构
|
||||
}else {
|
||||
//右边没有了,安心处理node
|
||||
result.add(node.val);
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 官方不改变树结构的stack法,使用一个pre记录之前的node,如果之前的node=root.right就说明右边的已经遍历完了
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public List<Integer> postorderTraversal4(TreeNode root) {
|
||||
List<Integer> res = new ArrayList<Integer>();
|
||||
if (root == null) {
|
||||
return res;
|
||||
}
|
||||
|
||||
Deque<TreeNode> stack = new LinkedList<TreeNode>();
|
||||
TreeNode prev = null;
|
||||
while (root != null || !stack.isEmpty()) {
|
||||
while (root != null) {
|
||||
stack.push(root);
|
||||
root = root.left;
|
||||
}
|
||||
root = stack.pop();
|
||||
if (root.right == null || root.right == prev) {
|
||||
//核心在于prev指针记录之前是否遍历他的右边
|
||||
res.add(root.val);
|
||||
prev = root;
|
||||
root = null;
|
||||
} else {
|
||||
stack.push(root);
|
||||
root = root.right;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 思路:Morris遍历:在不改变结构的情况下直接的Morris遍历是不行的,还是得中右左然后反向
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public List<Integer> postorderTraversal3(TreeNode root) {
|
||||
List<Integer> result = new ArrayList<>();
|
||||
|
||||
if(root==null){
|
||||
return result;
|
||||
}
|
||||
|
||||
TreeNode cur=root;
|
||||
|
||||
while (cur!=null){
|
||||
TreeNode node=cur.right;
|
||||
|
||||
if(node!=null){
|
||||
//存在右节点,寻找右子节点的最左节点
|
||||
while (node.left!=cur&&node.left!=null){
|
||||
node=node.left;
|
||||
}
|
||||
//判断是从啥条件出来的
|
||||
if(node.left==null){
|
||||
//第一次遍历到这
|
||||
node.left=cur;//将其连接
|
||||
result.add(cur.val);
|
||||
//放心将节点右移
|
||||
cur=cur.right;
|
||||
}else if(node.left==cur){
|
||||
//第二次遍历到这
|
||||
cur=cur.left;
|
||||
node.left=null;
|
||||
}
|
||||
}else {
|
||||
//右边为空了,遍历左节点去
|
||||
result.add(cur.val);
|
||||
cur=cur.left;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int size = result.size();
|
||||
List<Integer> result1 = new ArrayList<>();
|
||||
while (size>0){
|
||||
result1.add(result.get(--size));
|
||||
}
|
||||
return result1;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package com.markilue.leecode.tree.second;
|
||||
|
||||
import com.markilue.leecode.tree.TreeNode;
|
||||
import com.markilue.leecode.tree.TreeUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.tree.second
|
||||
*@Author: dingjiawen
|
||||
*@CreateTime: 2023-01-05 11:35
|
||||
*@Description:
|
||||
* TODO 二刷力扣94题 二叉树的中序遍历:
|
||||
* 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T03_InorderTraversal {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(3,1,2,5,6,7,8,10));
|
||||
TreeNode root = TreeUtils.structureTree(list, 0);
|
||||
System.out.println(inorderTraversal2(root));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 思路:递归法
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
List<Integer> result;
|
||||
public List<Integer> inorderTraversal(TreeNode root) {
|
||||
result=new ArrayList<>();
|
||||
midTraversal(root);
|
||||
return result;
|
||||
}
|
||||
public void midTraversal(TreeNode root) {
|
||||
if(root==null){
|
||||
return;
|
||||
}
|
||||
midTraversal(root.left);
|
||||
result.add(root.val);
|
||||
midTraversal(root.right);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 思路:stack非递归法
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public List<Integer> inorderTraversal1(TreeNode root) {
|
||||
ArrayList<Integer> result = new ArrayList<>();
|
||||
if(root==null){
|
||||
return result;
|
||||
}
|
||||
Stack<TreeNode> stack = new Stack<>();
|
||||
TreeNode cur=root;
|
||||
|
||||
while (cur!=null||!stack.isEmpty()){
|
||||
if(cur!=null){
|
||||
stack.push(cur);
|
||||
cur=cur.left;
|
||||
}else {
|
||||
TreeNode node = stack.pop();
|
||||
result.add(node.val);
|
||||
cur=node.right;//看看他的右边
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 思路:Morris遍历
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public List<Integer> inorderTraversal2(TreeNode root) {
|
||||
List<Integer> result = new ArrayList<>();
|
||||
if(root==null){
|
||||
return result;
|
||||
}
|
||||
|
||||
TreeNode cur=root;
|
||||
while (cur!=null){
|
||||
TreeNode node=cur.left;
|
||||
if(node!=null){
|
||||
while(node.right!=cur&&node.right!=null){
|
||||
node=node.right;
|
||||
}
|
||||
|
||||
if(node.right==null){
|
||||
node.right=cur;
|
||||
cur=cur.left;
|
||||
}else {
|
||||
//左边节点遍历完了
|
||||
node.right=null;
|
||||
result.add(cur.val);
|
||||
cur=cur.right;
|
||||
}
|
||||
}else {
|
||||
result.add(cur.val);//左边节点空了
|
||||
cur=cur.right;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
package com.markilue.leecode.tree.second;
|
||||
|
||||
import com.markilue.leecode.tree.TreeNode;
|
||||
import com.markilue.leecode.tree.TreeUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.tree.second
|
||||
*@Author: dingjiawen
|
||||
*@CreateTime: 2023-01-05 12:15
|
||||
*@Description:
|
||||
* TODO 力扣107题 二叉树的层序遍历 II:
|
||||
* 给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。
|
||||
* (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T041_LevelOrderBottom {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(3,9,20,null,null,15,7));
|
||||
TreeNode root = TreeUtils.structureTree(list, 0);
|
||||
System.out.println(levelOrderBottom1(root));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 思路:queue先层序后反向
|
||||
* 速度击败91.28%,内存击败6.48%
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public List<List<Integer>> levelOrderBottom(TreeNode root) {
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
if(root==null){
|
||||
return result;
|
||||
}
|
||||
|
||||
Deque<TreeNode> queue = new LinkedList<>();
|
||||
queue.offer(root);
|
||||
|
||||
while (!queue.isEmpty()){
|
||||
ArrayList<Integer> cur = new ArrayList<>();
|
||||
int size = queue.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
TreeNode node = queue.poll();
|
||||
cur.add(node.val);
|
||||
if(node.left!=null)queue.offer(node.left);
|
||||
if(node.right!=null)queue.offer(node.right);
|
||||
}
|
||||
result.add(cur);
|
||||
}
|
||||
Collections.reverse(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 思路:dfs深度优先递归
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
int maxDepth=0;
|
||||
public List<List<Integer>> levelOrderBottom1(TreeNode root) {
|
||||
|
||||
dfs(root,0);
|
||||
Collections.reverse(result);
|
||||
return result;
|
||||
}
|
||||
public void dfs(TreeNode root,int deep) {
|
||||
if(root==null){
|
||||
return;
|
||||
}
|
||||
if(result.size()==deep){
|
||||
result.add(new ArrayList<>());
|
||||
}
|
||||
dfs(root.left,deep+1);
|
||||
dfs(root.right,deep+1);
|
||||
result.get(deep).add(root.val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方直接加在头部法,避免反向
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public List<List<Integer>> levelOrderBottom2(TreeNode root) {
|
||||
List<List<Integer>> levelOrder = new LinkedList<List<Integer>>();
|
||||
if (root == null) {
|
||||
return levelOrder;
|
||||
}
|
||||
Queue<TreeNode> queue = new LinkedList<TreeNode>();
|
||||
queue.offer(root);
|
||||
while (!queue.isEmpty()) {
|
||||
List<Integer> level = new ArrayList<Integer>();
|
||||
int size = queue.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
TreeNode node = queue.poll();
|
||||
level.add(node.val);
|
||||
TreeNode left = node.left, right = node.right;
|
||||
if (left != null) {
|
||||
queue.offer(left);
|
||||
}
|
||||
if (right != null) {
|
||||
queue.offer(right);
|
||||
}
|
||||
}
|
||||
levelOrder.add(0, level);
|
||||
}
|
||||
return levelOrder;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package com.markilue.leecode.tree.second;
|
||||
|
||||
import com.markilue.leecode.tree.TreeNode;
|
||||
import com.markilue.leecode.tree.TreeUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.tree.second
|
||||
*@Author: dingjiawen
|
||||
*@CreateTime: 2023-01-05 11:58
|
||||
*@Description:
|
||||
* TODO 二刷力扣102题 二叉树的层序遍历:
|
||||
* 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T04_LevelOrder {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(3,9,20,null,null,15,7));
|
||||
TreeNode root = TreeUtils.structureTree(list, 0);
|
||||
System.out.println(levelOrder(root));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 思路:队列法
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public List<List<Integer>> levelOrder(TreeNode root) {
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
if(root==null){
|
||||
return result;
|
||||
}
|
||||
|
||||
Deque<TreeNode> queue = new LinkedList<>();
|
||||
queue.offer(root);
|
||||
|
||||
while (!queue.isEmpty()){
|
||||
int size = queue.size();
|
||||
List<Integer> cur = new ArrayList<>();//每层result
|
||||
for (int i = 0; i < size; i++) {
|
||||
TreeNode node = queue.poll();
|
||||
cur.add(node.val);
|
||||
if(node.left!=null)queue.offer(node.left);
|
||||
if(node.right!=null)queue.offer(node.right);
|
||||
}
|
||||
result.add(cur);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 官方最快:递归法,虽然是深度优先,但是他通过ans.get(depth)获取到第deep层的数列
|
||||
*/
|
||||
List<List<Integer>> ans = new ArrayList<>();
|
||||
public List<List<Integer>> levelOrder2(TreeNode root) {
|
||||
dfs(root, 0);
|
||||
return ans;
|
||||
}
|
||||
|
||||
public void dfs(TreeNode node, int depth) {
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
if (ans.size() == depth) {
|
||||
ans.add(new ArrayList<>());
|
||||
}
|
||||
ans.get(depth).add(node.val);
|
||||
dfs(node.left, depth + 1);
|
||||
dfs(node.right, depth + 1);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue