LeetCode LCP 07. 传递信息 / NC111 最大数 / NC16 判断二叉树是否对称 / NC13 二叉树的最大深度

祝我党百年华诞生日快乐

LCP 07. 传递信息

2021.7.1 每日一题

题目描述
小朋友 A 在和 ta 的小伙伴们玩传信息游戏,游戏规则如下:

有 n 名玩家,所有玩家编号分别为 0 ~ n-1,其中小朋友 A 的编号为 0
每个玩家都有固定的若干个可传信息的其他玩家(也可能没有)。传信息的关系是单向的(比如 A 可以向 B 传信息,但 B 不能向 A 传信息)。
每轮信息必须需要传递给另一个人,且信息可重复经过同一个人
给定总玩家数 n,以及按 [玩家编号,对应可传递玩家编号] 关系组成的二维数组 relation。返回信息从小 A (编号 0 ) 经过 k 轮传递到编号为 n-1 的小伙伴处的方案数;若不能到达,返回 0。

示例 1:

输入:n = 5, relation = [[0,2],[2,1],[3,4],[2,3],[1,4],[2,0],[0,4]], k = 3

输出:3

解释:信息从小 A 编号 0 处开始,经 3 轮传递,到达编号 4。共有 3 种方案,分别是 0->2->0->4, 0->2->1->4, 0->2->3->4。

示例 2:

输入:n = 3, relation = [[0,2],[2,1]], k = 2

输出:0

解释:信息不能从小 A 处经过 2 轮传递到编号 2

限制:

2 <= n <= 10
1 <= k <= 5
1 <= relation.length <= 90, 且 relation[i].length == 2
0 <= relation[i][0],relation[i][1] < n 且 relation[i][0] != relation[i][1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/chuan-di-xin-xi
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

深度优先搜索,或者广度优先搜索都可以
先将数组变成一个哈希表

class Solution {
    int res = 0;
    int n;
    public int numWays(int n, int[][] relation, int k) {
        //简单题,感觉写起来不简单啊
        //用一个<i ,list>存储
        this.n = n;
        int l = relation.length;
        Map<Integer, List<Integer>> map = new HashMap<>();
        for(int[] t : relation){
            List<Integer> list = map.getOrDefault(t[0], new ArrayList<>());
            list.add(t[1]);
            map.put(t[0], list); 
        }

        dfs(map, 0, k);
        return res;
    }

    public void dfs(Map<Integer, List<Integer>> map, int person, int k){
        if(k == 0 && person == n - 1){
            res++;
            return;
        }
        if(k == 0)
            return;
        List<Integer> list = map.get(person);
        if(list == null)
            return;
        for(int p : list){
            dfs(map, p, k - 1);
        }
    }
}

动态规划,dp[i][j]定义为第 i 轮传递到第 j 个人的方案数

class Solution {
    public int numWays(int n, int[][] relation, int k) {
        //看下动规,就记录所有的情况,然后再转移
        //dp[i][j] 表示第k轮传递到 person的方案数
        int l = relation.length;
        int[][] dp = new int[k + 1][n];
        //初始化,刚开始在0号人
        dp[0][0] = 1;
        for(int i = 0; i < k; i++){
            for(int[] t : relation){
                //从t[0]传递到t[1]
                dp[i + 1][t[1]] += dp[i][t[0]];
            }
        }
        return dp[k][n - 1];
    }
}

还可以利用矩阵快速幂,正好就是求的路径数目
https://www.cnblogs.com/Equinox-Flower/p/11726324.html#_label0

NC111 最大数

题目描述
给定一个数组由一些非负整数组成,现需要将他们进行排列并拼接,使得最后的结果最大,返回值需要是string类型 否则可能会溢出

示例1
输入:
[30,1]

返回值:
"301"
思路

主要还是排序问题,用字符串排序,从大到小排序
排序规则就是两个字符串拼接拼接以后的大小

import java.util.*;


public class Solution {
    /**
     * 最大数
     * @param nums int整型一维数组 
     * @return string字符串
     */
    public String solve (int[] nums) {
        // write code here
        //是一个排序问题
        int l = nums.length;
        String[] ss = new String[l];
        for(int i = 0; i < l; i++){
            ss[i] = String.valueOf(nums[i]);
        }
        //从大到小
        Arrays.sort(ss, new Comparator<String>(){
            public int compare(String s1, String s2){
                return (s2 + s1).compareTo(s1 + s2);
            }
        });
        if(ss[0].equals("0"))
            return "0";
        StringBuffer sb = new StringBuffer();
        for(String s : ss){
            sb.append(s);
        }
        return sb.toString();
    }
}

NC16 判断二叉树是否对称

题目描述
给定一棵二叉树,判断其是否是自身的镜像(即:是否对称)
例如:下面这棵二叉树是对称的
1
/  \
2    2
/ \    / \
3 4  4  3
下面这棵二叉树不对称。
1
/ \
2   2
\    \
3    3
备注:
希望你可以用递归和迭代两种方法解决这个问题
示例1
输入:
{1,2,2}
返回值:
true

示例2
输入:
{1,2,3,3,#,2,#}
返回值:
false
思路

都是剑指Offer的题,相当于复习了
递归

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    public boolean isSymmetric (TreeNode root) {
        // write code here
        if(root == null)
            return true;
        return same(root.left, root.right);
        
    }
    public boolean same(TreeNode left, TreeNode right){
        if(left == null && right == null)
            return true;
        if(left == null || right == null)
            return false;
        return left.val == right.val && same(left.left, right.right) && same(left.right, right.left);
    }
}

迭代

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    public boolean isSymmetric (TreeNode root) {
        // write code here
        if(root == null)
            return true;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root.left);
        queue.offer(root.right);
        while(!queue.isEmpty()){
            TreeNode n1 = queue.poll();
            TreeNode n2 = queue.poll();
            if(n1 == null && n2 == null)
                continue;
            if(n1 == null || n2 == null)
                return false;
            if(n1.val != n2.val)
                return false;
            queue.offer(n1.left);
            queue.offer(n2.right);
            queue.offer(n1.right);
            queue.offer(n2.left);
        }
        return true;
    }
}

NC13 二叉树的最大深度

题目描述
求给定二叉树的最大深度,
最大深度是指树的根结点到最远叶子结点的最长路径上结点的数量。

示例1
输入:
{1,2}

返回值:
2

示例2
输入:
{1,2,3,4,#,#,5}

返回值:
3
思路

广度优先搜索

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        // write code here
        if(root == null)
            return 0;
        int deep = 0;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            deep++;
            int size = queue.size();
            while(size-- > 0){
                TreeNode node = queue.poll();
                if(node.left != null)
                    queue.offer(node.left);
                if(node.right != null)
                    queue.offer(node.right);
            }
        }
        return deep;
    }
}

深度

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @return int整型
     */
    int max = 0;
    public int maxDepth (TreeNode root) {
        // write code here
        if(root == null)
            return 0;
        dfs(root, 0);
        return max;
    }
    
    public void dfs(TreeNode node, int deep){
        if(node == null){
            max = Math.max(max, deep);
            return;
        }
        dfs(node.left, deep + 1);
        dfs(node.right, deep + 1);
    }
}

或者

public class Solution {
    /**
     *
     * @param root TreeNode类
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        if(root == null) return 0; //节点为空返回0
        int lh = maxDepth(root.left); // 求出左子树的最大高度
        int rh = maxDepth(root.right); //求出右子树的最大高度
        return Math.max(lh,rh) + 1; //左右子树高度求一个最大然后+1
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值