leecode更新

This commit is contained in:
markilue 2023-01-05 12:53:55 +08:00
parent a768b112ca
commit 88bbded9ca
10 changed files with 541 additions and 8 deletions

View File

@ -4,7 +4,7 @@ package com.markilue.leecode.tree;
import java.util.List; import java.util.List;
import static com.markilue.leecode.tree.InorderTraversal.inorderTraversal1; import static com.markilue.leecode.tree.T03_InorderTraversal.inorderTraversal1;
/** /**
* 删除二叉排序树的某个节点 * 删除二叉排序树的某个节点

View File

@ -4,7 +4,7 @@ import org.junit.Test;
import java.util.List; import java.util.List;
import static com.markilue.leecode.tree.InorderTraversal.inorderTraversal1; import static com.markilue.leecode.tree.T03_InorderTraversal.inorderTraversal1;
/** /**
* @BelongsProject: Leecode * @BelongsProject: Leecode

View File

@ -13,7 +13,7 @@ import java.util.*;
* 给你二叉树的根节点 root 返回它节点值的 前序 遍历 * 给你二叉树的根节点 root 返回它节点值的 前序 遍历
* @Version: 1.0 * @Version: 1.0
*/ */
public class PostOrderTraversal { public class T02_PostOrderTraversal {
@Test @Test

View File

@ -8,7 +8,7 @@ import java.util.Stack;
/** /**
* 中序遍历二叉排序树 * 中序遍历二叉排序树
*/ */
public class InorderTraversal { public class T03_InorderTraversal {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -14,7 +14,7 @@ import java.util.*;
* 给你二叉树的根节点 root 返回其节点值的 层序遍历 即逐层地从左到右访问所有节点 * 给你二叉树的根节点 root 返回其节点值的 层序遍历 即逐层地从左到右访问所有节点
* @Version: 1.0 * @Version: 1.0
*/ */
public class LevelOrder { public class T04_LevelOrder {
@Test @Test
public void test() { public void test() {

View File

@ -2,11 +2,9 @@ package com.markilue.leecode.tree;
import org.junit.Test; import org.junit.Test;
import java.util.HashMap;
import java.util.List; 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 * @BelongsProject: Leecode

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}