Leetcode刷题 2021.01.09

Leetcode1372 二叉树中的最长交错路径

给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下:

选择二叉树中 任意 节点和一个方向(左或者右)。
如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。
改变前进方向:左变右或者右变左。
重复第二步和第三步,直到你在树中无法继续移动。
交错路径的长度定义为:访问过的节点数目 - 1(单个节点的路径长度为 0 )

请你返回给定树中最长 交错路径 的长度。

愉快的二叉树题。想一想对于一颗数要返回什么。求全局最大肯定是要用一个全局变量在递归里更新了。对于一颗二叉树,可以返回左右子树的交错路径的长度,然后加上自身的长度再返回就行了。再注意区分左右和root==null的时候就行了。

class Solution {
	//全局变量
    int max = 0;
    public int longestZigZag(TreeNode root) {
        helper(root);
        return max;
    }

    private int[] helper(TreeNode root){
    	//等于null返回-1
        if (root == null) return new int[]{-1, -1};
        int[] l = helper(root.left);
        int[] r = helper(root.right);
        //l和r表示左右子树的交错路径最大值,然后更新,左子树的右边的交错路径和右子树左边路径的交错路径
        max = Math.max(max, Math.max(l[1] + 1,  r[0] + 1));
        //返回即可
        return new int[]{l[1] + 1, r[0] + 1};
    }
}

Leetcode1311 获取你好友已观看的视频

有 n 个人,每个人都有一个 0 到 n-1 的唯一 id 。

给你数组 watchedVideos 和 friends ,其中 watchedVideos[i] 和 friends[i] 分别表示 id = i 的人观看过的视频列表和他的好友列表。

Level 1 的视频包含所有你好友观看过的视频,level 2 的视频包含所有你好友的好友观看过的视频,以此类推。一般的,Level 为 k 的视频包含所有从你出发,最短距离为 k 的好友观看过的视频。

给定你的 id 和一个 level 值,请你找出所有指定 level 的视频,并将它们按观看频率升序返回。如果有频率相同的视频,请将它们按字母顺序从小到大排列。

基本就是BFS的模板题,最后返回的时候要按照给定的排序顺序返回。对各种数据结构综合应用的题吧。

class Solution {
    public List<String> watchedVideosByFriends(List<List<String>> watchedVideos, int[][] friends, int id, int level) {
    	//map用来最后保存词频
        Map<String, Integer> map = new HashMap<>();
        //set用来保存已经访问过的结点
        Set<Integer> isVisited = new HashSet<>();
        //BFS使用queue
        Queue<Integer> queue = new LinkedList<>();
        isVisited.add(id);
        for(int ele : friends[id]){
            queue.offer(ele);
            isVisited.add(ele);
        }
        int count = 1;
        while (!queue.isEmpty()){
            if (count == level) break;
            int n = queue.size();
            for(int i = 0; i < n; i++){
                int temp = queue.poll();
                for(int ele : friends[temp]){
                    if (!isVisited.contains(ele)){
                        queue.offer(ele);
                        isVisited.add(ele);
                    }
                }
            }
            count++;
        }
        //统计词频
        while (!queue.isEmpty()){
            int temp = queue.poll();
            for(String ele : watchedVideos.get(temp)){
                map.put(ele, map.getOrDefault(ele, 0) + 1);
            }
        }
        List<String> res = new ArrayList<>();
        for(String s : map.keySet()){
            res.add(s);
        }
        //对结果进行排序,字典序排列用compareTo()
        Collections.sort(res, (x, y) -> (map.get(x) == map.get(y) ? x.compareTo(y) : map.get(x) - map.get(y)));

        return res;
    }
}

Leetcode1382 用户分组

有 n 位用户参加活动,他们的 ID 从 0 到 n - 1,每位用户都 恰好 属于某一用户组。给你一个长度为 n 的数组 groupSizes,其中包含每位用户所处的用户组的大小,请你返回用户分组情况(存在的用户组以及每个组中用户的 ID)。

你可以任何顺序返回解决方案,ID 的顺序也不受限制。此外,题目给出的数据保证至少存在一种解决方案。

输入:groupSizes = [3,3,3,3,3,1,3]
输出:[[5],[0,1,2],[3,4,6]]

之前做过一道类似的什么兔子的题。一上来就是排序,所以这题也没多想,用优先队列进行排序,然后保存映射关系做的。看了题解使用map做的,时间复杂度是O(n)。其实思想还是保存映射关系,没时间优化了,要去写论文了,先这样吧。

class Solution {
    public List<List<Integer>> groupThePeople(int[] groupSizes) {
    	//用优先队列保存映射关系
        PriorityQueue<int[]> queue = new PriorityQueue<>((x, y) -> (x[0] - y[0]));
        for(int i = 0; i < groupSizes.length; i++){
            queue.offer(new int[]{groupSizes[i], i});
        }
        List<List<Integer>> res = new ArrayList<>();
        //从队列里面拿出来,加到list中
        while (!queue.isEmpty()){
            List<Integer> list = new ArrayList<>();
            int[] temp = queue.poll();
            list.add(temp[1]);
            for(int i = 1; i < temp[0]; i++){
                list.add(queue.poll()[1]);
            }
            res.add(list);
        }
        return res;

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值