leetcode随笔2

leetcode深度优先遍历学习2

昨天做了几个比较简单的题。今天适当增加一点难度。

113.路径总和2
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

这个题很明显是要利用优先遍历来实现。思路也比较简单,当遍历到一个路径的结束时,比较当前路径和是否等于目标值。相等的话就把这条路径加入到结果集中。

class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int sum) {
        List<List<Integer>> pathList = new LinkedList<>();
        if(root == null){
            return pathList;
        }

        List<Integer> path = new LinkedList<>();
        getPath(pathList,path,root,sum,0);
        return pathList;
    }

    public void getPath(List<List<Integer>> list,List<Integer> path,TreeNode root,int sum,int curSum){
        curSum += root.val;
        path.add(root.val);
        if(root.left == null && root.right == null){
            if(sum == curSum){
                List<Integer> temp = new LinkedList<>();
                for(int a : path){
                    temp.add(a);
                }
                list.add(temp);
            }
        }else{
            if(root.left != null){
                getPath(list,path,root.left,sum,curSum);
            }
            if(root.right != null){
                getPath(list,path,root.right,sum,curSum);
            }
        }
        path.remove(path.size() - 1);
        curSum -= root.val;
    }
}

二叉树展开为链表
给定一个二叉树,原地将它展开为链表。

第一眼看到这个题目,我的第一反应是把根节点的左右节点先变成链表,之后再把这两个链表拼接在一起。之后实现起来遇到了问题,想了很久还是没有解决的思路。最后参照了别人的做法才做出来。
思路是这样的:每次将一个节点的右节点拼接到左子树的最右节点上,之后再将左节点变为它的右节点,再将它的左节点设为null。

class Solution {
    public void flatten(TreeNode root) {
        while(root != null){
            if(root.left != null){
                TreeNode temp = root.left;
                while(temp.right != null){
                    temp = temp.right;
                }
                temp.right = root.right;
                root.right = root.left;
                root.left = null;
            }
            root = root.right;
        }
    }
}

我觉得需要注意的一点是原地展开,而不是返回一个新的链表。

116. 填充每个节点的下一个右侧节点指针
给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。

我还是太菜了。这个题我是用了队列来实现了广度优先遍历。即借助了辅助空间,效率也不高。

class Solution {
    public Node connect(Node root) {
        if(root == null){
            return root;
        }

        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
        Node pre = null;
        int layer = 0;
        while(!queue.isEmpty()){
            int cur = (int)Math.pow(2,layer);
            while(cur != 0){
                Node node = queue.poll();
                if(pre == null){
                    pre = node;
                }else{
                    pre.next = node;
                    pre = node;
                }
                if(node.left != null){
                    queue.offer(node.left);
                }
                if(node.right != null){
                    queue.offer(node.right);
                }
                cur--;
            }
            pre = null;
            layer++;
        }
        
        return root;
    }
}

之后看了别人的实现思路,发现自己确实还是有很大不足。
因为是完美二叉树,所以节点的next存在两种情况。一种是一个节点的左右子节点,而另一种就是跨父节点的next(该节点的右节点与该节点的next节点的左节点)。

class Solution {
    public Node connect(Node root) {
        if(root == null){
            return root;
        }
        if(root.left != null){
            root.left.next = root.right;
            if(root.next != null){
                root.right.next = root.next.left;
            }
            connect(root.left);
            connect(root.right);
        }
        return root;
    }
}

129. 求根到叶子节点数字之和
给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。
例如,从根到叶子节点路径 1->2->3 代表数字 123。
计算从根到叶子节点生成的所有数字之和。
说明: 叶子节点是指没有子节点的节点。

感觉这题和之前做的路径和的题有点类似。主要思路是深度遍历一条路径,当遍历到叶节点时,将这个数加入到列表(辅助存储)中。之后再将列表的所有值都加起来。

class Solution {
    public int sumNumbers(TreeNode root) {
        if(root == null){
            return 0;
        }
        StringBuilder str = new StringBuilder();
        ArrayList<Integer> list = new ArrayList<>();
        getNums(root,str,list);
        int sum = 0;
        for(int a : list){
            sum += a;
        }
        return sum;
    }

    public void getNums(TreeNode root,StringBuilder str,ArrayList<Integer> list){
        str.append(root.val);
        if(root.left == null && root.right == null){
            list.add(Integer.parseInt(str.toString()));
        }
        if(root.left != null){
            getNums(root.left,str,list);
        }
        if(root.right != null){
            getNums(root.right,str,list);
        }
        str.delete(str.length() - 1,str.length());
    }
}

emmm,我现在在做leetcode130题,但是被卡住了。临时有点事,先更到这,我明天继续做。
加油加油。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值