day16 树左下角的值 深拷贝

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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值