个人主页:Ice_Sugar_7
所属专栏:数据结构刷题
欢迎点赞收藏加关注哦!
题目链接
思路:采用层序遍历的思路,遍历每一层的时候,先创建一个数组存放该层节点,遍历完一层后,取出最右边的节点(即数组最后一个元素),将它们的val都存进顺序表ret,返回即可
class Solution {
public List<Integer> rightSideView(TreeNode root) {
if(root == null)
return new ArrayList<>();
//层序遍历,一层一个数组,每层取该层数组最后一个元素
List<Integer> list = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()) {
List<Integer> list1 = new ArrayList<>();
int size = queue.size();
while(size-- > 0) {
TreeNode pop = queue.poll();
if(pop.left != null) {
queue.offer(pop.left);
}
if(pop.right != null) {
queue.offer(pop.right);
}
list1.add(pop.val);
}
int last = list1.get(list1.size()-1); //得到该层最右的节点的val
list.add(last);
}
return list;
}
}
涉及到的知识点:
- 层序遍历
题目链接
思路:公共祖先节点有两种情况
第一种情况:此时root就是祖先节点
第二种情况:祖先节点就是q或p,在遍历的过程中,先遍历到谁,谁就是祖先节点(假设q是祖先节点,那这种情况下,p一定在q的子树之中)
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null)
return null;
if(root == p)
return p;
if(root == q)
return q;
//遍历左、右子树找q、p
TreeNode ret1 = lowestCommonAncestor(root.left,p,q);
TreeNode ret2 = lowestCommonAncestor(root.right,p,q);
//如果ret1和ret2都不为空,就是第一种情况
//若有一个为空,则是第二种
//有的节点向左右子树找是找不到的,此时要返回null
if(ret1 != null && ret2 != null) {
return root;
} else if(ret1 == null && ret2 != null) {
return ret2;
} else if(ret1 != null && ret2 == null) {
return ret1;
} else {
return null;
}
}
}
以上是第一种解法,接下来说另一种
我们可以参考相交链表找相交点的思路。之前是单链表,现在是二叉树,区别在于二叉树没办法存储遍历过的节点
两个辅助栈
来存储节点pop1 == pop2
时,说明这个节点就是相交节点class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode cur = root;
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
getPath(cur,q,stack1);
getPath(cur,p,stack2);
int sizeQ = stack1.size();
int sizeP = stack2.size();
if(sizeQ > sizeP) {
int size = sizeQ - sizeP;
while(size-- > 0) {
stack1.pop();
}
}
if(sizeQ < sizeP) {
int size = sizeP - sizeQ;
while(size-- > 0) {
stack2.pop();
}
}
while(!stack1.isEmpty()) {
TreeNode pop1 = stack1.pop();
TreeNode pop2 = stack2.pop();
if(pop1.val == pop2.val) {
return pop1;
}
}
return root;
}
private boolean getPath(TreeNode root,TreeNode node,Stack<TreeNode> stack) {
if(root == null)
return false;
//一定要在比较root和node的val之前入栈,否则可能会导致路径上最后一个节点没入栈
stack.push(root);
if(root.val == node.val)
return true;
boolean ret1 = getPath(root.left,node,stack);
if(!ret1) {
//左边找不到就去找右边
boolean ret2 = getPath(root.right,node,stack);
if(!ret2) { //右边还是找不到的话,说明这条路径上没有我们要找的节点,那就把这个节点出栈
stack.pop();
return false;
}
}
return true;
}
}
题目链接
思路:对每个根节点进行分类讨论,分析如何添加括号
每次递归之前,都先加上左括号,递归出来后,加上右括号
如果某棵子树为空,那我们就不用再往这棵子树递归下去了
class Solution {
StringBuilder ret = new StringBuilder();
public String tree2str(TreeNode root) {
if(root == null)
return new String();
ret.append(root.val);
//对根节点进行分析
//1.左右都空:不处理
//2.左空右不空:补整个括号
//3.左不空右空:不处理
if(root.left != null) {
ret.append('(');
//处理左树
tree2str(root.left);
ret.append(')'); //处理完补右括号
} else {
if(root.right != null) {
ret.append("()");
}
}
//处理右树
if(root.right != null) {
ret.append('(');
tree2str(root.right);
ret.append(')');
}
return ret.toString();
}
}