LCP 07. 传递信息
小朋友 A 在和 ta 的小伙伴们玩传信息游戏,游戏规则如下:
- 有 n 名玩家,所有玩家编号分别为 0 ~ n-1,其中小朋友 A 的编号为 0
- 每个玩家都有固定的若干个可传信息的其他玩家(也可能没有)。传信息的关系是单向的(比如 A 可以向 B 传信息,但 B 不能向 A 传信息)。
- 每轮信息必须需要传递给另一个人,且信息可重复经过同一个人
给定总玩家数 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。
怎么求解?
- 先说思路
有很多解法,其中最快上手的肯定是DFS,很像全排列,一个个坐标穷举,递归走k-1次,看有几个到n-1位置就行
要点:
(1)二维数组要用数据结构处理下,避免每次都for循环On,最好处理成O1;
(2)DFS代码要很娴熟
刷题进度
- 完成立马刷题
- 隔一天再刷一次
- 代码
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);
}
}
}
学习要点:
- 处理二维数组的数据结构
Map<Integer,Set<Integer>>
绝了,key放当前位置坐标,Set放能走到的位置。 - 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;
}
}
学习要点:
- 截图思路很简单其实,可能比简单题还要简单
- 二维数组的处理是最考验人的,一定要记清楚,第一维度是行,第二维度是列
2325. 解密消息
给你字符串 key 和 message ,分别表示一个加密密钥和一段加密消息。解密 message 的步骤如下:
- 使用 key 中 26 个英文小写字母第一次出现的顺序作为替换表中的字母 顺序 。
- 将替换表与普通英文字母表对齐,形成对照表。
- 按照对照表 替换 message 中的每个字母。
- 空格 ' ' 保持不变。
- 例如,key = "happy boy"(实际的加密密钥会包含字母表中每个字母 至少一次),据此,可以得到部分对照表('h' -> 'a'、'a' -> 'b'、'p' -> 'c'、'y' -> 'd'、'b' -> 'e'、'o' -> 'f')。
返回解密后的消息。
示例1:
输入: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);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类