114_二叉树展开为链表
package 二叉树.BT; import java.util.ArrayList; import java.util.Deque; import java.util.LinkedList; import java.util.List; /** * https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/ * @author Huangyujun * * 编程里有很重要的一个思维:就是记录“第一次的结果”,然后等到走到“第二次的结果”时进行一些操作 * 可能式第二次的结果与第一次进行比较, * 也可能是(比较之后)将第二次结果覆盖掉第一次结果 * 所以编程里非常重要的变量:标记变量:即记录“第一次的结果”(前一次的结果),留个“第二次的结果”(当前的结果)进行比较 */ public class _114_二叉树展开为链表 { 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; } } //题意:左指针变成null,右指针指向下个结点(不断取出当前结点,跟下一个结点 //题目给提示了呀:“展开后的单链表应该与二叉树 先序遍历 顺序相同。” //咱就利用先序遍历的递归或者迭代遍历到每个结点,将其添加到list 集合中,(为什么要添加到List 而不直接操作:) //理由:咱需要重塑一颗树的形状呀(不是你想变就能变) //然后咱再遍历每个结点,将其左指针指向null,右指针指向下个结点(构建出链式形状) public void flatten(TreeNode root) { List<TreeNode> list = new ArrayList<TreeNode>(); preorderTraversal(root, list); int size = list.size(); for (int i = 1; i < size; i++) { TreeNode prev = list.get(i - 1), curr = list.get(i); prev.left = null; prev.right = curr; } } public void preorderTraversal(TreeNode root, List<TreeNode> list) { if (root != null) { list.add(root); preorderTraversal(root.left, list); preorderTraversal(root.right, list); } } //题意:左指针变成null,右指针指向下个结点 //记录第一个结点prevNode: //然后 走到第二个结点currNode,让第一个结点prev 的左指针指向null,右指针 指针 第二个结点 public void flatten2(TreeNode root) { if (root == null) { return; } Deque<TreeNode> queue = new LinkedList<TreeNode>(); queue.push(root); TreeNode prev = null; while (!queue.isEmpty()) { TreeNode curr = queue.pop(); if (prev != null) { //通过 prev != null 判断得知:当前结点是第二个(来到了下一次)啦 prev.left = null; prev.right = curr; } TreeNode left = curr.left, right = curr.right; if (right != null) { queue.push(right); } if (left != null) { queue.push(left); } prev = curr; //记录第一次“前一次的结果” } } }