[Leedcode][JAVA][第94/144/145题][前中后序遍历][递归][迭代][二叉树]
【問(wèn)題描述】[]
- 前序遍歷 先輸出當(dāng)前結(jié)點(diǎn)的數(shù)據(jù),再依次遍歷輸出左結(jié)點(diǎn)和右結(jié)點(diǎn)
- 中序遍歷 先遍歷輸出左結(jié)點(diǎn),再輸出當(dāng)前結(jié)點(diǎn)的數(shù)據(jù),再遍歷輸出右結(jié)點(diǎn)
- 后續(xù)遍歷 先遍歷輸出左結(jié)點(diǎn),再遍歷輸出右結(jié)點(diǎn),最后輸出當(dāng)前結(jié)點(diǎn)的數(shù)據(jù)
【解答思路】
遞歸 /迭代(棧)
時(shí)間復(fù)雜度:O(N) 空間復(fù)雜度:O(N)
1. 前序遍歷
1.1 遞歸
二叉樹(shù)遍歷(前序、中序、后序)的遞歸方法,唯一改變的是記錄節(jié)點(diǎn)值操作的位置
1.2 迭代(棧)
需要一個(gè)輔助棧
2. 中序遍歷
1.1 遞歸
二叉樹(shù)遍歷(前序、中序、后序)的遞歸方法,唯一改變的是記錄節(jié)點(diǎn)值操作的位置
1.2 迭代(棧)
需要一個(gè)輔助棧
3. 后序遍歷
1.1 遞歸
二叉樹(shù)遍歷(前序、中序、后序)的遞歸方法,唯一改變的是記錄節(jié)點(diǎn)值操作的位置
1.2 迭代(棧)
需要兩個(gè)輔助棧
-從根節(jié)點(diǎn)開(kāi)始依次迭代,彈出棧頂元素輸出到輸出列表中,然后依次壓入它的所有孩子節(jié)點(diǎn),按照從上到下、從左至右的順序依次壓入棧中。
-因?yàn)樯疃葍?yōu)先搜索后序遍歷的順序是從下到上、從左至右,所以需要將輸出列表逆序輸出。
class Solution {List<Integer> res = new ArrayList<>();public List<Integer> postorderTraversal(TreeNode root) {if (root == null) {return res;}LinkedList<TreeNode> stack = new LinkedList<>();LinkedList<TreeNode> stackTemp = new LinkedList<>();stackTemp.push(root);while (!stackTemp.isEmpty()) {TreeNode curNode = stackTemp.pop();//stack壓入stack.push(curNode);if (curNode.left != null) {stackTemp.push(curNode.left);}if (curNode.right != null) {stackTemp.push(curNode.right);}}//逆序while (!stack.isEmpty()) {res.add(stack.pop().val);}return res;} }1.3 轉(zhuǎn)換思想 后續(xù)轉(zhuǎn)前序 逆轉(zhuǎn)
后序遍歷的順序是 左 -> 右 -> 根。
前序遍歷的順序是 根 -> 左 -> 右,
左右其實(shí)是等價(jià)的,所以我們也可以輕松的寫(xiě)出 根 -> 右 -> 左 的代碼。
然后把 根 -> 右 -> 左 逆序,就是 左 -> 右 -> 根,也就是后序遍歷了。
1.4 一個(gè)棧
public List<Integer> postorderTraversal(TreeNode root) {if (root == null) return new ArrayList<Integer>();TreeNode node = root;List<Integer> ret = new ArrayList<Integer>();Stack<TreeNode> stack = new Stack<TreeNode>();while(node != null || !stack.isEmpty()) {while (node != null) {stack.push(node);node = node.left;}node = stack.pop();// 后序遍歷// 如果沒(méi)有右孩子或者右孩子被訪問(wèn)過(guò)了 {@Alex Zheng 感謝建議哈~}if (node.right == null || (ret.size() != 0 && ret.get(ret.size() - 1).equals(node.right.val)) ) {ret.add(node.val);node = null;} else {stack.push(node);node = node.right;}}return ret;}鏈接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/bian-li-tong-jie-by-long_wotu/【總結(jié)】
1. 前中后序遍歷變化的是[中]的位置,左到右的順序不改變
- 前序遍歷 中左右
- 中序遍歷 左中右
- 后續(xù)遍歷 左右中
2.pop 與 poll 都是取出 LinkedList 的第一個(gè)元素,并將該元素刪除,等效于:removeFirst
不同點(diǎn):兩者的實(shí)現(xiàn)所用數(shù)據(jù)結(jié)構(gòu)不同,
- poll 是基于隊(duì)列結(jié)構(gòu)實(shí)現(xiàn)的方法,當(dāng)隊(duì)列中沒(méi)有元素時(shí),調(diào)用該方法返回 null
- pop 是基于棧結(jié)構(gòu)實(shí)現(xiàn)的方法,當(dāng)棧中沒(méi)有元素時(shí),調(diào)用該方法會(huì)發(fā)生異常
3. 遞歸模板
res.add(root.val); 位置動(dòng)態(tài)變化
public List<Integer> preorderTraversal(TreeNode root) {if (root != null) {//先序遍歷 res.add(root.val);preorderTraversal(root.left);//中序遍歷 res.add(root.val);preorderTraversal(root.right);//后序遍歷 res.add(root.val);}return res;}4. 迭代模板
list.add(cur.val);位置動(dòng)態(tài)變化
前中序可遍歷,后續(xù)遍歷可由前序遍歷修改后逆轉(zhuǎn)
參考鏈接:https://leetcode.wang/leetcode-145-Binary-Tree-Postorder-Traversal.html
總結(jié)
以上是生活随笔為你收集整理的[Leedcode][JAVA][第94/144/145题][前中后序遍历][递归][迭代][二叉树]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 青岛智能院助力智慧城市 打造智能产业“黄
- 下一篇: dp递推 hdu1978