leetcode 513 树左下角的值
这道题BFS DFS都可以做
BFS思路:遍历每一层,把每一层最左边的节点值打印出来
DFS思路:找到最深的一层,打印这一层最左边的节点的值
我是用BFS做的,套用BFS模板
bfs(root) {
queue = []
queue.push(root)
while queue.length {
curLevel = queue
queue = []
for i = 0 to curLevel.length {
doSomething(curLevel[i])
if (curLevel[i].left) {
queue.push(curLevel[i].left)
}
if (curLevel[i].right) {
queue.push(curLevel[i].right)
}
}
}
}
java代码实现
public static int findBottomLeftValue(TreeNode root) {
if (root==null) throw new RuntimeException("空树");
int res=0;
ArrayList<TreeNode> line =new ArrayList<>();
ArrayList<ArrayList<TreeNode>> allline=new ArrayList<>();
line.add(root);
while (line.size()!=0){
// ArrayList<TreeNode> curline=new ArrayList<>();
ArrayList<TreeNode> curline = (ArrayList<TreeNode>) line.clone();//深拷贝列表
line.clear();
for (TreeNode treeNode : curline) {
if (treeNode==null) continue;
if (treeNode.left!=null) line.add(treeNode.left);
if (treeNode.right!=null) line.add(treeNode.right);
}
allline.add(curline);
}
if (allline.size()!=0) {
ArrayList<TreeNode> treeNodes = allline.get(allline.size() - 1);
res=treeNodes.get(0).val;
}
return res;
}
遇到的问题:
因为在遍历每一层的时候都需要先做一次深拷贝,然后把当前列表清空,在做列表深拷贝的时候补习一下深拷贝的知识
我们平时做列表copy的时候是浅拷贝,这样你在修改原列表的时候,新列表也会跟着变,这是因为新列表是把原列表元素的地址值直接拷贝过来的,并没有用新的地址值。如果是我们自己写的类,需要继承Cloneable接口重写clone()方法。
ArrayList本身带有clone()方法,查看源码我们发现返回的是一个Object类型的数据,但是已经做了深拷贝
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
我们只需要把结果强转成我们需要的就好ArrayList<TreeNode> curline = (ArrayList<TreeNode>) line.clone();
备注一下,其实这里用队列就可以搞定,我们在遍历的时候每次把队列的头元素弹出来,最后自然又是个空队列了,不过需要我们先记录上次队列的长度
int len = queue.size();
for(int i=0;i<len;i++){
TreeNode node = queue.poll();
list.add(node.val);
if(node.left!=null){
queue.offer(node.left);
}if(node.right!=null){
queue.offer(node.right);
}
}
最后附一个大佬的深搜的解答过程
class Solution {
int maxdep=0;
int ans;
public int findBottomLeftValue(TreeNode root) {
withdeep(root,1);
return ans;
}
public void withdeep(TreeNode root,int dep){
if(root.left==null && root.right==null){
if(dep>maxdep){
maxdep=dep;
ans=root.val;
}
}
if(root.left!=null) withdeep(root.left,dep+1); //因为是找到最左边的,所以先进行左子树查找
if(root.right!=null) withdeep(root.right,dep+1);
}
}