栈【二叉树遍历】

329. 仿 LISP 运算

import java.util.Scanner;
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
         Scanner in = new Scanner(System.in);
        String s = in.nextLine().replace("div", "/").replace("mul", "*")
                .replace("add", "+").replace("sub", "-");
        Deque<String> stack = new ArrayDeque<>();
        int res = 0;
        for (int i = 0; i < s.length(); i++) {
            String temp = s.substring(i, i + 1);
            if (!temp.equals(")")){ //  入栈
                stack.push(temp);
                continue;
            }
            StringBuilder sb = new StringBuilder();
            while (!"(".equals(stack.peek())){
                sb.insert(0, stack.pop());
            }
            String[] split = sb.toString().split(" ");
            String slogan = split[0];
            int a = Integer.parseInt(split[1]);
            int b = Integer.parseInt(split[2]);
            if ("/".equals(slogan) && b == 0){
                System.out.println("error");
                return;
            }
            res = cal(slogan, a, b);
            stack.pop();    //  弹出 "("
            stack.push(res + "");
        }
        System.out.println(res);
    }
    public static int cal(String str, int a, int b){
        if ("/".equals(str)){
            if (a / b < 0 && a % b != 0){
                return a / b - 1;
            }
            return a / b;
        }
        if ("-".equals(str)){
            return a - b;
        }
        if ("+".equals(str)){
            return a + b;
        }
        return a * b;
    }
}

263. 荒岛求生

每次加入新的时候,就要进行判断是否要进行 PK!!!

import java.util.Scanner;
import java.util.*;


// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
       Scanner in = new Scanner(System.in);
        String[] split = in.nextLine().split(" ");
        int[] arr = new int[split.length];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = Integer.parseInt(split[i]);
        }
        Deque<Integer> stack = new ArrayDeque<>();
        for (int i : arr) {
             if (i == 0){
                System.out.println(-1);
                return;
            }

            if (stack.isEmpty()){
                stack.push(i);
                continue;
            }
            Integer peek = stack.peek();
            if (peek * i > 0){
                stack.push(i);
            }else { //  异号
                if (peek > 0 && i < 0){ //  PK
                    if (peek + i == 0){ //  2个全死
                        stack.pop();
                    }else {
                        while (!stack.isEmpty() && stack.peek() * i < 0 && stack.peek() > 0){
                            i = stack.pop() + i;    //  待加入的
                        }
                        if (i != 0){
                            stack.push(i);
                        }
                    }
                }else {
                    stack.push(i);
                }
            }
        }
        System.out.println(stack.size());
    }
}

312. 二叉树中序遍历

import java.util.Scanner;
import java.util.Scanner;
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Deque<Node> stack = new ArrayDeque<>();
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        for (int i = 0; i < s.length(); i++) {
            String now = s.substring(i, i + 1);
            if (!"}".equals(now)){
                if (",".equals(now)){
                    stack.push(new Node(","));
                }else if ("{".equals(now)){
                    stack.push(new Node("-1"));
                }else {
                    stack.push(new Node(now));
                }
                continue;
            }
            //  碰到了 } ==> 开始收割
            List<Node> temp = new ArrayList<>();
            while (!"-1".equals(stack.peek().val)){
                temp.add(stack.pop());
            }
            stack.pop();    //  弹出 {
            Node peek = stack.peek();
            if (temp.size() == 3){
                Node left = temp.get(2);
                Node right = temp.get(0);
                peek.left = left;
                peek.right = right;
            }else if (temp.size() == 2){
                Node right = temp.get(0);
                peek.right = right;
            }else if (temp.size() == 1){
                Node left = temp.get(0);
                peek.left = left;
            }
        }
        inOrder(stack.peek());
    }

    public static void inOrder(Node node){
        if (node == null){
            return;
        }
        inOrder(node.left);
        System.out.print(node.val);
        inOrder(node.right);
    }
}
class Node{
    String val;
    Node left;
    Node right;

    public Node(String val) {
        this.val = val;
    }
}

数组二叉树

最小叶子节点的路径为3 7 2。
# 输入
3 5 7 -1 -1 2 4
# 输出
3 7 2

package com.ooooo;

import java.util.*;

/**
 * @Author: Ronnie LEE
 * @Date: 2023/10/16 - 10 - 16 - 10:12
 * @Description: com.ooooo
 * @version: 1.0
 */
public class Tree {
    static List<TreeNode> list = new ArrayList<>();
    static List<List<Integer>> lists = new ArrayList<>();
    static int min = Integer.MAX_VALUE;
    static StringBuilder res = new StringBuilder();

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] split = in.nextLine().split(" ");
        TreeNode[] arr = new TreeNode[split.length];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new TreeNode(Integer.parseInt(split[i]));
        }
        //  找规律
        //  父:i、左:2 * i,右:2 * i + 1
        TreeNode left = null;
        TreeNode right = null;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i].val != -1) {
                if (2 * i + 1 < arr.length && arr[2 * i + 1].val != -1) {
                    left = arr[2 * i + 1];
                }else {
                    left = null;
                }
                if (2 * i + 2 < arr.length && arr[2 * i + 2].val != -1) {
                    right = arr[2 * i + 2];
                }else {
                    right = null;
                }
                TreeNode treeNode = arr[i];
                treeNode.left = left;
                treeNode.right = right;
            }
        }
        System.out.println(arr[0]);
        dfs(arr[0]);
        System.out.println("===========");
        System.out.println(lists);
        System.out.println(res.toString().trim());
    }
    public static void dfs(TreeNode treeNode){
        if (treeNode == null){
            return;
        }
        if (treeNode.left == null && treeNode.right == null){
            list.add(treeNode); //  TreeNode 是叶子节点
            if (min > treeNode.val){
                min = treeNode.val;
                System.out.println("333");
                res.setLength(0);
                for (TreeNode node : list) {
                    res.append(node.val + " ");
                }
            }
            List<Integer> temp = new ArrayList<>();
            for (TreeNode node : list) {
                temp.add(node.val);
            }
            lists.add(new ArrayList<>(temp));
            Tree.list.remove(Tree.list.size() - 1);   //  回溯!!!
            return;
        }
       list.add(treeNode);
       dfs(treeNode.left);
       dfs(treeNode.right);
    }
}

class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "val=" + val +
                ", left=" + left +
                ", right=" + right +
                '}';
    }
}

完全二叉树非叶子部分后序遍历

import java.util.Scanner;
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    static int[] arr;
    static StringBuilder res = new StringBuilder();
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] split = in.nextLine().split(" ");
        arr = new int[split.length];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = Integer.parseInt(split[i]);
        }
        Node root = getRoot(0);
          if (root.left == null && root.right == null){  //  特殊情况:只有一个根节点
            System.out.println(root.val);
            return;
        }
        backtracking(root);
        System.out.println(res.toString().trim());
    }
    public static void backtracking(Node node){
        if (node == null){
            return;
        }
        if (node.left == null && node.right == null){
            return;
        }
        backtracking(node.left);
        backtracking(node.right);
        res.append(node.val + " ");
    }


    public static Node getRoot(int i){
        Node node = new Node(arr[i]);
        if (2 * i + 1 < arr.length){
            node.left = getRoot(2 * i + 1);
        }
        if (2 * i + 2 < arr.length){
            node.right = getRoot(2 * i + 2);
        }
        return node;
    }
}
class Node{
    int val;
    Node left;
    Node right;

    public Node(int val) {
        this.val = val;
    }
}

二叉树的广度优先遍历

package com.lllp;

import javax.swing.tree.TreeNode;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;

/**
 * @Author: Ronnie LEE
 * @Date: 2023/10/16 - 10 - 16 - 16:56
 * @Description: com.lllp
 * @version: 1.0
 */
public class ooo {
    //  CBEFDA:后序
    //  CBAEDF:中序
    static String strA;
    static Deque<Node> deque = new ArrayDeque<>();
    static StringBuilder res = new StringBuilder();

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] split = in.nextLine().split(" ");
        strA = split[0];
        Node node = getNode(split[1]);
        System.out.println(node);
        deque.offer(node);
        bfs();
        System.out.println(res);
    }

    public static Node getNode(String strB){    //  中序
        int index = -1;
        for (int i = strA.length(); i >= 1; i--) {
            String root = strA.substring(i - 1, i);
            if (strB.contains(root)){
                index = strB.indexOf(root);
                break;
            }
        }
        Node node = new Node(strB.substring(index, index + 1));
        String left = strB.substring(0, index);
        if (!"".equals(left)){
            node.left = getNode(left);
        }
        
        String right = strB.substring(index + 1);  //  这里无需特殊处理,substring 第一个参数可以等于长度,这样得到的结果就是 ""
        if (!"".equals(right)){
            node.right = getNode(right);
        }
        return node;
    }

    public static void bfs(){
        while (!deque.isEmpty()){
            int size = deque.size();
            while (size > 0){
                Node node = deque.poll();
                res.append(node.val);
                if (node.left != null){
                    deque.offer(node.left);
                }
                if (node.right != null){
                    deque.offer(node.right);
                }
                size--;
            }
        }
    }
}

class Node{
    String val;
    Node left;
    Node right;

    public Node(String val) {
        this.val = val;
    }

    @Override
    public String toString() {
        return "Node{" +
                "val='" + val + '\'' +
                ", left=" + left +
                ", right=" + right +
                '}';
    }
}

327. 二维伞的雨滴效应

import java.util.Scanner;
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] split = in.nextLine().split(" ");
        int[] arr = new int[split.length];
        //  判断是否是 BST:是否是 BST 的前序遍历【根 左 右】
        //  中序【左 根 右】
        List<Integer> temp = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = Integer.parseInt(split[i]);
            temp.add(arr[i]);
            list.add(arr[i]);
        }
        Collections.sort(list);

        //  不是 BST的 情形
        if (!isValid(arr, 0, arr.length - 1, Integer.MIN_VALUE, Integer.MAX_VALUE)){
            System.out.println(0 + " " + 0 + " " + 0);
            return;
        }
        TreeNode root = getRoot(arr, list);
 if (root.val == getLeft(root, 0).val && root.val != getRight(root, 0).val){
            System.out.println("1" + " " + 0 + " " + getRight(root, 0).val);
            return;
        }
        if (root.val != getLeft(root, 0).val && root.val == getRight(root, 0).val){
            System.out.println("1" + " " + getLeft(root, 0).val + " " + 0);
            return;
        }
        if (root.val == getLeft(root, 0).val && root.val == getRight(root, 0).val){
            System.out.println("1" + " " + 0 + " " + 0);
            return;
        }

        System.out.println("1" + " " + getLeft(root, 0).val + " " + getRight(root, 0).val);
    }
    public static TreeNode getRoot(int[] arr, List<Integer> list){
        int index = -1;
        for (int i = 0; i < arr.length; i++) {
            if (list.contains(arr[i])){
                index = Collections.binarySearch(list, arr[i]);//  以根节点进行分割
                break;
            }
        }
        TreeNode treeNode = new TreeNode(list.get(index));
        List<Integer> left = list.subList(0, index);
        if (left.size() > 0){
            treeNode.left = getRoot(arr, left);
        }
        List<Integer> right = list.subList(index + 1, list.size());
        if (right.size() > 0){
            treeNode.right = getRoot(arr, right);
        }
        return treeNode;
    }
    public static TreeNode getLeft(TreeNode root, int len){
        if (root.left == null){
            if (len == 0){
                return root;
            }else {
                if (root.right != null){
                    return getLeft(root.right, len + 1);
                }
            }
        }else {
            return getLeft(root.left, len + 1);
        }
        return root;
    }

   public static TreeNode getRight(TreeNode root, int len){
        if (root.right == null){
            if (len == 0){
                return root;
            }else {
                if (root.left != null){
                    return getRight(root.left, len + 1);
                }
            }
        }else {
            return getRight(root.right, len + 1);
        }
        return root;
    }
    public static boolean isValid(int[] arr, int start, int end, int min, int max){
        if (start > end){   //  当前没有左子树,正确
            return true;
        }
        int rootValue = arr[start];
        if (rootValue < min || rootValue > max){
            return false;
        }
        int index = start;
        while (index + 1 <= end && arr[index + 1] <= rootValue){
            index++;    //  截断点
        }
        boolean leftSubtree = isValid(arr, start + 1, index, min, rootValue - 1);
        boolean rightSubtree = isValid(arr, index + 1, end, rootValue + 1, max);
        return leftSubtree && rightSubtree;
    }
}

class TreeNode{
    int val;    //  输入的数组的任意两个数字都互不相同
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
    }
}

662. 二叉树最大宽度【BFS:为每一个节点配置对应的下标】

/**
 * 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 {
	Deque<TreeNode> deque = new ArrayDeque<>();
	int res = 0;
	List<Integer> list = new ArrayList<>();	//	存储下标!!!
	public int widthOfBinaryTree(TreeNode root) {
		//	每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度
		//	结合 二叉树 的数组表示
		list.add(1);
		deque.offer(root);
		bfs();
		return res;
	}

	public void bfs(){
		while (!deque.isEmpty()){
			int len = deque.size();
			while (len > 0) {
				TreeNode peek = deque.poll();
				int index = list.get(0);
				list.subList(0, 1).clear();	//	弹出第一个坐标
				if (peek.left != null){
					deque.offer(peek.left);
					list.add(2 * index);	//	左孩子下标 【相当于为每一个节点,设置了和它相匹配的下标】
				}
				if (peek.right != null){
					deque.offer(peek.right);
					list.add(2 * index + 1);	//	右孩子下标
				}
				len--;
			}
			if (list.size() == 1 || list.size() == 0){
				res = Math.max(res, 1);
			}else {
				res = Math.max(res, list.get(list.size() - 1) - list.get(0) + 1);	//	由于是求个数:所以 + 1
			}
		}
	}
}

155. 最小栈【栈中存放的是:数组】

class MinStack {
    Deque<Integer[]> stack;

    //  设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
    public MinStack() {
        stack = new ArrayDeque<>();
    }
    
    public void push(int val) {
        if (stack.isEmpty()){
            stack.push(new Integer[]{val, val});
            return;
        }
        stack.push(new Integer[]{val, Math.min(val, stack.peek()[1])});
    }
    
    public void pop() {
       stack.pop();
    }
    
    public int top() {
       return stack.peek()[0];
    }
    
    public int getMin() {
        return stack.peek()[1];
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(val);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

1038. 从二叉搜索树到更大和树【再探 BST】

前置:BST的中序遍历为:顺序排序
注意:此前一直用的是:左 中 右
那么变换下思维:右 中 左 的话,就成为了 逆序排序
BST最右侧为最大值
我们的 sum 记录的是比当前大的和

class Solution {
	//	BST中序是按照顺序的
	//	树中所有值都不重复
	//	左小右大 ===> 右侧都是比当前大的
	int sum = 0;

	public TreeNode bstToGst(TreeNode root) {
		inOrder(root);
		return root;
	}

	public void inOrder(TreeNode node){
    	if (node == null){
    		return;
		}
		inOrder(node.right);
    	node.val += sum;
    	sum = node.val;  //  更新 sum
    	inOrder(node.left);
	}
}

437. 路径总和Ⅲ【3次递归】

class Solution {
	int res = 0;
    public int pathSum(TreeNode root, int targetSum) {
    	inOrder(root, targetSum);
    	return res;
    }
    public void inOrder(TreeNode node, int targetSum){
    	if (node == null){
    		return;
		}
    	getResult(node, targetSum, node.val);	//	遍历每一个数组
    	inOrder(node.left, targetSum);
    	inOrder(node.right, targetSum);
	}

	public void getResult(TreeNode node, int targetSum, long val){
    	if (val == targetSum){
    		res++;
		}
    	if (node.left != null) {
			getResult(node.left, targetSum, val + node.left.val);
		}
    	if (node.right != null) {
			getResult(node.right, targetSum, val + node.right.val);
		}
	}
}

124. 二叉树中的最大路径和【⭐】

class Solution {
	int res = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
		suffixOrder(root);
		return res;
    }

    public int suffixOrder(TreeNode node){
    	if (node == null){
    		return 0;
		}
		int leftVal = suffixOrder(node.left);
		int rightVal = suffixOrder(node.right);
		res = Math.max(res, node.val + leftVal + rightVal);
		return Math.max(Math.max(leftVal, rightVal) + node.val, 0);  //  如果负收益的话,就舍弃,即:取 0
	}
}
posted @ 2023-10-14 12:09  爱新觉罗LQ  阅读(15)  评论(0编辑  收藏  举报