資料結構每日學習 Day1 二元樹

2022-01-04 23:00:01

第一題:

114. 二元樹展開為連結串列
在這裡插入圖片描述
解題:
首先回顧一下 二元樹的遞迴遍歷和迭代遍歷

遞迴遍歷如下:
(三種遍歷方式只需調整add語句位置即可)

    public void dfs(TreeNode root,List<TreeNode> list){
        if (root!=null){
            list.add(root);
            dfs(root.left,list);
            dfs(root.right,list);
        }

    }

迭代遍歷+Morris解法如下:

https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/leetcodesuan-fa-xiu-lian-dong-hua-yan-shi-xbian-2/
中序迭代(自認為好理解的):

public static void inOrderIteration(TreeNode head) {
	if (head == null) {
		return;
	}
	TreeNode cur = head;
	Stack<TreeNode> stack = new Stack<>();
	while (!stack.isEmpty() || cur != null) {
		while (cur != null) {
			stack.push(cur);
			cur = cur.left;
		}
		TreeNode node = stack.pop();
		System.out.print(node.value + " ");
		if (node.right != null) {
			cur = node.right;
		}
	}
}


前序迭代:(這個畫個圖 理解一下就很快)

public static void preOrderIteration(TreeNode head) {
	if (head == null) {
		return;
	}
	Stack<TreeNode> stack = new Stack<>();
	stack.push(head);
	while (!stack.isEmpty()) {
		TreeNode node = stack.pop();
		System.out.print(node.value + " ");
		if (node.right != null) {
			stack.push(node.right);
		}
		if (node.left != null) {
			stack.push(node.left);
		}
	}
}


感覺下面這個更好理解一些

Deque<TreeNode> stack = new LinkedList<TreeNode>();
        TreeNode node = root;
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                list.add(node);
                stack.push(node);
                node = node.left;
            }
            node = stack.pop();
            node = node.right;
        }


AC:

package 二元樹;

import java.util.ArrayList;
import java.util.List;

public class 二元樹展開為連結串列 {
  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;
      }
  }

  /*
  Queue<TreeNode> queue = new ArrayDeque<>();
        preOrder(root, queue);
        while (!queue.isEmpty()){
            TreeNode curr = queue.poll();
            curr.left = null;
            curr.right = queue.peek();
        }
    }
   */
    public void flatten(TreeNode root) {
        List<TreeNode> list=new ArrayList<TreeNode>();
        dfs(root,list);
        int len=list.size();
        
        for (int i = 1; i <len ; i++) {
            //原本下面這一行錯了 注意理解
            TreeNode prev = list.get(i - 1), curr = list.get(i);
            prev.left=null;
            prev.right=curr;

        }



    }
    public void dfs(TreeNode root,List<TreeNode> list){
        if (root!=null){
            list.add(root);
            dfs(root.left,list);
            dfs(root.right,list);
        }

    }
}

第二題:543. 二元樹的直徑
在這裡插入圖片描述

在這裡插入圖片描述
AC:(太妙了 首先你要會深度是怎麼求的 !!! )(這個遞迴過程建議反覆咀嚼)

class Solution {
    int ans;
    public int diameterOfBinaryTree(TreeNode root) {
        ans = 1;
        depth(root);
        return ans - 1;
    }
    public int depth(TreeNode node) {
        if (node == null) {
            return 0; // 存取到空節點了,返回0
        }
        int L = depth(node.left); // 左兒子為根的子樹的深度
        int R = depth(node.right); // 右兒子為根的子樹的深度
        ans = Math.max(ans, L+R+1); // 計算d_node即L+R+1 並更新ans
        return Math.max(L, R) + 1; // 返回該節點為根的子樹的深度
    }
}