🤞目录🤞
【大家好,我是爱干饭的猿,如果喜欢这篇文章,点个赞👍,关注一下吧,后续会一直分享题目与算法思路】
🚠1. 按之字形顺序打印二叉树
描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
例如:
给定的二叉树是{1,2,3,#,#,4,5}
编辑
该二叉树之字形层序遍历的结果是
[
[1],
[3,2],
[4,5]
]
解题思路:
🎈思路一:本质也是对树形结构的层序遍历,不过在遍历的过程中,需要更改遍历顺序
我们可以采用queue的方式来进行处理
核心思路:不论当前层从左向右遍历还是从右向左遍历,都是下层就从left到right入队并且list.add(元素),只是当前层如果从右向左遍历,将list集合元素逆置即可(详见代码)
🎈思路二:我们可以也采用stack和queue的方式来进行处理
核心思路:当前层从左向右遍历,那么下层就从left到right入栈,当前层如果从右向左遍历,那么下层就从right到 left入栈(详见代码)
🌅思路一:代码如下:
// 方法一: public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) { if(pRoot == null){ return new ArrayList<>(); } ArrayList<ArrayList<Integer>> result = new ArrayList<>(); Queue<TreeNode> queue = new LinkedList<>(); queue.offer(pRoot); // 1 表示正序 ,2 表示逆序 // 先默认flag为2 ,进入while时 保证第一次是正序 int flag = 2; while (!queue.isEmpty()){ ArrayList<Integer> list = new ArrayList<>(); ArrayList<Integer> reList = new ArrayList<>(); int size = queue.size(); flag = flag == 2 ? 1 : 2; for (int i = 0; i < size; i++) { TreeNode cur = queue.poll(); if(flag == 1){ list.add(cur.val); }else { reList.add(cur.val); } if(cur.left != null) queue.offer(cur.left); if(cur.right != null) queue.offer(cur.right); } // 将该层数逆置存入list for (int i = reList.size()-1; i >= 0 ; i--) { list.add(reList.get(i)); } result.add(list); } return result; }
🌅思路二:代码如下:
// 方法二: public ArrayList<ArrayList<Integer>> Print2(TreeNode pRoot) { ArrayList<ArrayList<Integer>> result = new ArrayList<>(); if (pRoot == null) { return result; } Stack<TreeNode> st = new Stack<>(); Queue<TreeNode> q = new LinkedList<>(); //临时区域 st.push(pRoot); int dir = 1; //1:代表left->right式入栈. 2: 代表right->left式入栈 ArrayList<Integer> list = new ArrayList<>();//保存一层结果的临时变量 while (!st.empty()) { int size = st.size(); //清空本层所有节点,将下层节点按照要求入栈,栈具有天然的逆序的能力 for (int i = 0; i < size; i++) { TreeNode curr = st.pop(); list.add(curr.val); TreeNode first = (dir == 1) ? curr.left : curr.right; TreeNode second = (dir == 1) ? curr.right : curr.left; if (first != null) q.offer(first); if (second != null) q.offer(second); } //本层遍历完毕,入结果集 result.add(new ArrayList(list)); //一定要注意浅拷贝问题 list.clear(); //将所有节点入栈,进行逆序 while (!q.isEmpty()) { st.push(q.poll()); } dir = (dir == 1) ? 2 : 1; } return result; }
🚠2. 二叉搜索树的第k个节点
描述
给定一棵结点数为n 二叉搜索树,请找出其中的第 k 小的TreeNode结点值。
1.返回第k小的节点值即可
2.不能查找的情况,如二叉树为空,则返回-1,或者k大于n等等,也返回-1
3.保证n个节点的值不一样
例如:
输入{5,3,7,2,4,6,8},3时,二叉树{5,3,7,2,4,6,8}如下图所示:
编辑
该二叉树所有节点按结点值升序排列后可得[2,3,4,5,6,7,8],所以第3个结点的结点值为4,故返回对应结点值为4的结点即可。
解题思路:
🎈思路一:BST本身就是有序的,中序遍历即是升序
要求第k小,即中序遍历时到达第k个元素(二叉搜索树,不存在两个相同的节点值)
此处,我们不使用递归,我们采用循环中序遍历的方式(详见代码)
🌅思路一:代码如下:
public int KthNode (TreeNode proot, int k) { if(proot == null || k <= 0){ return -1; } Stack<TreeNode> stack = new Stack<>(); TreeNode cur = proot; while (cur != null || !stack.isEmpty()){ // 层序遍历,先走到最小值(最左) while (cur != null){ stack.push(cur); cur = cur.left; } if(!stack.isEmpty()){ // 出栈k次 cur = stack.pop(); k--; if(k == 0){ return cur.val; } } cur = cur.right; } return -1; }
🚠3. 二叉搜索树的第k大节点
描述
给定一棵二叉搜索树,请找出其中第
k
大的节点的值。例如:
编辑
解题思路:
🎈思路一:和上一题几乎一模一样,
只是现在要求第k大,即中序遍历变式(右根左)时到达第k个元素(二叉搜索树,不存在两个相同的节点值) (详见代码)
🌅思路一:代码如下:
public int kthLargest(TreeNode root, int k) { if(root == null || k <= 0){ return 0; } Stack<TreeNode> stack = new Stack<>(); TreeNode cur = root; while (!stack.isEmpty() || cur != null){ // 层序遍历变式(右根左),先走到最大值(最右) while (cur != null){ stack.push(cur); cur = cur.right; } if(!stack.isEmpty()){ // 出栈k次 cur = stack.pop(); k -- ; if(k == 0){ return cur.val; } } cur = cur.left; } return 0; }