算法戴高乐计划-03篇-题目

发布时间 2023-10-10 09:56:47作者: 大元王保保

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代码要很娴熟

刷题进度

  • 完成立马刷题
  • 隔一天再刷一次
  1. 代码
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算法基础模型还是要好好训练下,很重要。

1267. 统计参与通信的服务器

有一幅服务器分布图,服务器的位置标识在 m * n 的整数矩阵网格 grid 中,1 表示单元格上有服务器,0 表示没有。
如果两台服务器位于同一行或者同一列,我们就认为它们之间可以进行通信。统计能够与至少一台其他服务器进行通信服务器的数量。
示例1:
输入:grid = [[1,0],[1,1]]
输出:3
解释:所有这些服务器都至少可以与一台别的服务器进行通信
示例2:
输入:grid = [[1,1,0,0],[0,0,1,0],[0,0,1,0],[0,0,0,1]]
输出:4
解释:第一行的两台服务器互相通信,第三列的两台服务器互相通信,但右下角的服务器无法与其他服务器通信。

class Solution {
    public int countServers(int[][] grid) {
        int row = grid.length;
        int column = grid[0].length;
	//这样用来处理行
        int[] rowArray = new int[row];
	//这样用来处理列
        int[] columnArray = new int[column];
        for(int i=0;i<row;i++){
            for(int j=0;j<column;j++){
                // 如果当前坐标为1,就当前行 当前列数量都+1 这样每一行有多少个 有一列有多少个就算出来了
                if(grid[i][j]==1){
                    rowArray[i]++;
                    columnArray[j]++;
                }
            }
        }
        int result = 0;
        for(int i=0;i<row;i++){
            for(int j=0;j<column;j++){
                if(grid[i][j]==1&&(rowArray[i]>1||columnArray[j]>1)){
                   result++; 
                }
            }
        }
        return result;
    }
}

学习要点:

  1. 截图思路很简单其实,可能比简单题还要简单
  2. 二维数组的处理是最考验人的,一定要记清楚,第一维度是行,第二维度是列

2325. 解密消息

给你字符串 key 和 message ,分别表示一个加密密钥和一段加密消息。解密 message 的步骤如下:

  1. 使用 key 中 26 个英文小写字母第一次出现的顺序作为替换表中的字母 顺序 。
  2. 将替换表与普通英文字母表对齐,形成对照表。
  3. 按照对照表 替换 message 中的每个字母。
  4. 空格 ' ' 保持不变。
  • 例如,key = "happy boy"(实际的加密密钥会包含字母表中每个字母 至少一次),据此,可以得到部分对照表('h' -> 'a'、'a' -> 'b'、'p' -> 'c'、'y' -> 'd'、'b' -> 'e'、'o' -> 'f')。
    返回解密后的消息。
    示例1:
    image
    输入:key = "the quick brown fox jumps over the lazy dog", message = "vkbs bs t suepuv"
    输出:"this is a secret"
    解释:对照表如上图所示。
    提取 "the quick brown fox jumps over the lazy dog" 中每个字母的首次出现可以得到替换表。
class Solution {
    public String decodeMessage(String key, String message) {
        // 统计第一次出现的顺序表
        char[] keyArray = new char[26];
        char map = 'a';
        for(int i=0;i<key.length();i++){
            char curr = key.charAt(i);
            if(curr == ' ') continue;
            if(keyArray[curr-'a'] == 0){
                // 其实不在乎怎么存,只要能对应起来就行,我一直在纠结第一个数一定要存t 其实不是
                // 这个存就相当于 array[t]=a,array[h]=b...
                keyArray[curr-'a'] = map;
                map++;
            }
        }
        char[] messChars= message.toCharArray();
        for (int i = 0; i < message.length(); i++) {
            if(messChars[i] == ' ') continue;
            // array[t] 就是要解的值,直接放进来就好了!
            messChars[i] = keyArray[messChars[i] - 'a'];
        }
        return String.valueOf(messChars);
    }
}