算法戴高乐计划-01篇

发布时间 2023-09-14 21:14:28作者: 大元王保保

LCP 07. 传递信息

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

  1. 有 n 名玩家,所有玩家编号分别为 0 ~ n-1,其中小朋友 A 的编号为 0
  2. 每个玩家都有固定的若干个可传信息的其他玩家(也可能没有)。传信息的关系是单向的(比如 A 可以向 B 传信息,但 B 不能向 A 传信息)。
  3. 每轮信息必须需要传递给另一个人,且信息可重复经过同一个人

给定总玩家数 n,以及按 [玩家编号,对应可传递玩家编号] 关系组成的二维数组 relation。返回信息从小 A (编号 0 ) 经过 k 轮传递到编号为 n-1 的小伙伴处的方案数;若不能到达,返回 0。

比如:
输入: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。

怎么求解?

  1. 先说思路
    有很多解法,其中最快上手的肯定是DFS,很像全排列,一个个坐标穷举,递归走k-1次,看有几个到n-1位置就行
    要点:
    (1)二维数组要用数据结构处理下,避免每次都for循环On,最好处理成O1;
    (2)DFS代码要很娴熟

  2. 代码

class Solution {
    Map<Integer, Set<Integer>> map = new HashMap<>();
    int result = 0;
    public int numWays(int n, int[][] relation, int k) {
        // 转化数据模型,方便取,不然每次都要遍历
        for(int [] arr:relation ){
            Set<Integer> set  = map.getOrDefault(arr[0] , new HashSet<>());
            set.add(arr[1]);
            map.put(arr[0],set);
        }
        dfs(0,0,k,n);
        return result;
    }
    void dfs(int current, int levels,int k,int n){
        if(levels == k){
            if(current == n-1) result++;
            return;
        }
        // 当前节点能到达的位置
        Set<Integer> set = map.get(current);
        if(set == null) return;
        for(int index : set){
            dfs(index,levels+1,k,n);
        }
    }
}

学习要点:

  1. 处理二维数组的数据结构
    Map<Integer,Set<Integer>>绝了,key放当前位置坐标,Set放能走到的位置。
  2. DFS算法基础模型还是要好好训练下,很重要。