剑指offer56-60
1、按之字形顺序打印二叉树
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
输入:
{1,2,3,#,#,4,5}
返回值:
[[1],[3,2],[4,5]]
说明:
如题面解释,第一层是根节点,从左到右打印结果,第二层从右到左,第三层从左到右。
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer> > list2 = new ArrayList<ArrayList<Integer> >();
ArrayList<Integer> list1 = new ArrayList<Integer>();
if(pRoot == null){
return list2;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(pRoot);
int count=0;
while(!queue.isEmpty()){
list1 = new ArrayList<Integer>();
int size = queue.size();
count++;
for( int i = 0;i < size; i++){
TreeNode node = queue.poll();
if(count % 2 !=0){
list1.add(node.val);
}
else {
list1.add(0,node.val);
}
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
list2.add(list1);
}
return list2;
}
2、二叉树中和为某一值的路径(一)
描述
给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
输入:
输入:
{5,4,8,1,11,#,9,#,#,2,7},22
返回值:
true
public class Solution {
/**
*
* @param root TreeNode类
* @param sum int整型
* @return bool布尔型
*/
public boolean hasPathSum (TreeNode root, int sum) {
// write code here
if(root == null){
return false;
}
return judge(root,sum);
}
public boolean judge(TreeNode root,int sum){
if(root == null){
return false;
}
sum -= root.val;
if(root.left == null && root.right == null && 0 == sum){
return true;
}
return judge(root.left,sum) || judge(root.right,sum);
}
}
3、二叉树中和为某一值的路径(二)
描述
输入一颗二叉树的根节点root和一个整数expectNumber,找出二叉树中结点值的和为expectNumber的所有路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
输入:
{10,5,12,4,7},22
返回值:
[[10,5,7],[10,12]]
说明:
返回[[10,12],[10,5,7]]也是对的
public class Solution {
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
LinkedList<Integer> list1 = new LinkedList<Integer>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int expectNumber) {
if(root == null){
return list;
}
judge(root,expectNumber);
return list;
}
public void judge(TreeNode root,int sum){
if(root == null){
return;
}
sum -= root.val;
list1.add(root.val);
if(root.left == null && root.right == null && 0 == sum){
list.add(new ArrayList<>(list1));
}
judge(root.left,sum);
judge(root.right,sum);
list1.removeLast();
}
}
4、二叉树中和为某一值的路径(三)
题目的主要信息:
- 给定一个二叉树root和一个整数值 sum ,求该树有多少路径的的节点值之和等于 sum
- 路径定义不需要从根节点开始,也不需要在叶子节点结束,但是一定是从父亲节点往下到孩子节点,如下图所示:
-
具体做法:
- step 1:每次将原树中遇到的节点作为子树的根节点送入dfs函数中查找有无路径,如果该节点为空则返回。
- step 2:然后递归遍历这棵树每个节点,每个节点都需要这样操作。
- step 3:在dfs函数中,也是往下递归,遇到一个节点就将sum减去节点值再往下。
- step 4:剩余的sum等于当前节点值则找到一种情况。
public class Solution {
int res = 0;
public int FindPath (TreeNode root, int sum) {
// write code here
if(root == null)return 0;
path(root,sum);
FindPath(root.left,sum);
FindPath(root.right,sum);
return res;
}
public void path(TreeNode node, int sum){
if(node == null){
return;
}
if(sum == node.val)res++;
path(node.left,sum - node.val);
path(node.right,sum - node.val);
}
}
5、在二叉树中找到两个节点的最近公共祖先
给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。
数据范围:树上节点数满足 1 \le n \le 10^5 \1≤n≤105 , 节点值val满足区间 [0,n)
要求:时间复杂度 O(n)O(n)
注:本题保证二叉树中每个节点的val值均不相同。
public int lowestCommonAncestor(TreeNode root, int o1, int o2) {
return helper(root, o1, o2).val;
}
public TreeNode helper(TreeNode root, int o1, int o2) {
if (root == null || root.val == o1 || root.val == o2)
return root;
TreeNode left = helper(root.left, o1, o2);
TreeNode right = helper(root.right, o1, o2);
//如果left为空,说明这两个节点在root结点的右子树上,我们只需要返回右子树查找的结果即可
if (left == null)
return right;
//同上
if (right == null)
return left;
//如果left和right都不为空,说明这两个节点一个在root的左子树上一个在root的右子树上,
//我们只需要返回cur结点即可。
return root;
}