当前位置: 首页 > article >正文

代码随想录算法训练营第四十六四十七天

卡码网题目:

  • 110. 字符串接龙
  • 105. 有向图的完全联通
  • 106. 岛屿的周长
  • 107. 寻找存在的路径

其他:

今日总结
往期打卡


110. 字符串接龙

跳转: 110. 字符串接龙

学习: 代码随想录公开讲解

问题:

字典 strList 中从字符串 beginStr 和 endStr 的转换序列是一个按下述规格形成的序列:

  1. 序列中第一个字符串是 beginStr。

  2. 序列中最后一个字符串是 endStr。

  3. 每次转换只能改变一个字符。

  4. 转换过程中的中间字符串必须是字典 strList 中的字符串,且strList里的每个字符串只用使用一次。

给你两个字符串 beginStr 和 endStr 和一个字典 strList,找到从 beginStr 到 endStr 的最短转换序列中的字符串数目。如果不存在这样的转换序列,返回 0。

思路:

这题的关键是如何构图,可以提前建好字典,通过遍历各位替换字母查看新建字符串是否合法来遍历下一个位置
也可以通过构建分别清除各位字母剩下字母对可能值列表的映射来确认一次转换后可能到达的位置

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码(字母替换):

import java.util.*;
public class Main{public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();String beginStr = scanner.next();String endStr = scanner.next();List<String> wordList = new ArrayList<>();wordList.add(beginStr);wordList.add(endStr);for(int i=0;i<n;i++){wordList.add(scanner.next());}int count = bfs(beginStr,endStr,wordList);System.out.println(count);}public static int bfs(String beginStr,String endStr,List<String> wordList){int len = 1;Set<String> set = new HashSet<>(wordList);Set<String> visited = new HashSet<>();Queue<String> queue = new LinkedList<>();visited.add(beginStr);queue.add(beginStr);queue.add(null);while(!queue.isEmpty()){String node = queue.poll();if(node==null){if(!queue.isEmpty()){len++;queue.add(null);}continue;}char[] charArrays = node.toCharArray();for(int i=0;i<charArrays.length;i++){char old = charArrays[i];for(char j = 'a';j<='z';j++){charArrays[i] = j;String newWord = new String(charArrays);if(set.contains(newWord)&&!visited.contains(newWord)){queue.add(newWord);visited.add(newWord);if(newWord.equals(endStr)) return len+1;}}charArrays[i] = old;}}return 0;}
}

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n 2 ) O(n^2) O(n2)

代码(字母映射):

import java.util.*;
class Main{public static  void main(String[] args){Scanner sc = new Scanner(System.in);int N = sc.nextInt();String beginStr = sc.next();String endStr = sc.next();List<Map<String,List<String>>> maps = new ArrayList<>();for(int i=0;i<endStr.length();i++){String sub = endStr.substring(0,i)+endStr.substring(i+1);Map<String, List<String>> map = new HashMap<>();List<String> list = new ArrayList<>();list.add(endStr);map.put(sub,list);maps.add(map);}for(int i=0;i<N;i++){String tmp = sc.next();for(int j=0;j<endStr.length();j++){String sub = tmp.substring(0,j)+tmp.substring(j+1);Map<String, List<String>> map = maps.get(j);List<String> list = map.getOrDefault(sub,new ArrayList<>());list.add(tmp);map.put(sub,list);}}Set<String> vis = new HashSet<>();Queue<String> queue = new LinkedList<>();queue.add(beginStr);int ans = 1;while(!queue.isEmpty()){int l = queue.size();ans++;for(int i=0;i<l;i++){String tmp = queue.poll();for(int j=0;j<endStr.length();j++){String sub = tmp.substring(0,j)+tmp.substring(j+1);Map<String, List<String>> map = maps.get(j);List<String> list = map.getOrDefault(sub,new ArrayList<>());if(list.contains(endStr)){System.out.println(ans);return;}for(String str:list){if(vis.contains(str)) continue;vis.add(str);queue.add(str);}}}}System.out.println(0);}
}

105. 有向图的完全联通

跳转: 105. 有向图的完全联通

学习: 代码随想录公开讲解

问题:

给定一个有向图,包含 N 个节点,节点编号分别为 1,2,…,N。现从 1 号节点开始,如果可以从 1 号节点的边可以到达任何节点,则输出 1,否则输出 -1。

例:
在这里插入图片描述
从 1 号节点可以到达任意节点,输出 1。

思路:

直接标记好bfs即可

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码:

import java.util.*;class Main {private static boolean bfs(Map<Integer, List<Integer>> map, int x, int N) {Queue<Integer> queue = new LinkedList<>();Set<Integer> vis = new HashSet<>();vis.add(x);queue.add(x);while (!queue.isEmpty()) {int tmp = queue.poll();for (int i : map.getOrDefault(tmp, new ArrayList<>())) {if (vis.contains(i)) continue;queue.add(i);vis.add(i);}}return vis.size() == N;}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();int K = sc.nextInt();Map<Integer, List<Integer>> map = new HashMap<>();for (int i = 0; i < K; i++) {int x = sc.nextInt();int y = sc.nextInt();List<Integer> list = map.getOrDefault(x, new ArrayList<>());list.add(y);map.put(x, list);}if (bfs(map, 1, N))System.out.println(1);else System.out.println(-1);}
}

106. 岛屿的周长

跳转: 106. 岛屿的周长

学习: 代码随想录公开讲解

问题:

给定一个由 1(陆地)和 0(水)组成的矩阵,岛屿是被水包围,并且通过水平方向或垂直方向上相邻的陆地连接而成的。

你可以假设矩阵外均被水包围。在矩阵中恰好拥有一个岛屿,假设组成岛屿的陆地边长都为 1,请计算岛屿的周长。岛屿内部没有水域。

例:
在这里插入图片描述
岛屿的周长为 14。

思路:

边长和周围不是陆地的长度是一致的(越界或水都是边界,算1单位边长),直接bfs即可

复杂度:

  • 时间复杂度: O ( n m ) O(nm) O(nm)
  • 空间复杂度: O ( n m ) O(nm) O(nm)

代码:

import java.util.*;class Main {public static void main(String[] args) {int ans = 0;int[][] DISTANCE = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};Scanner sc = new Scanner(System.in);int N = sc.nextInt();int M = sc.nextInt();int[][] map = new int[N][M];for (int i = 0; i < N; i++)for (int j = 0; j < M; j++)map[i][j] = sc.nextInt();for (int i = 0; i < N; i++)for (int j = 0; j < M; j++)if (map[i][j] == 1)for (int k = 0; k < 4; k++) {int n = i + DISTANCE[k][0];int m = j + DISTANCE[k][1];if (n < 0 || m < 0 || n >= map.length || m >= map[0].length || map[n][m] == 0)ans++;}System.out.println(ans);}
}

并查集理论

学习: 代码随想录公开讲解

并查集就是把同类节点串起来,用父级是否相等判断是否有关联(对于无向图而言即:是否联通)

有两种优化方法,路径压缩和按秩合并

  • 路径压缩就是查找父级后递归回去的过程直接指向最前父级
    在这里插入图片描述

  • 按秩合并就是如果树深度不同小深度连到大的身上,减少最大查询深度的增加.
    在这里插入图片描述

107. 寻找存在的路径

跳转: 107. 寻找存在的路径

学习: 代码随想录公开讲解

问题:

给定一个包含 n 个节点的无向图中,节点编号从 1 到 n (含 1 和 n )。

你的任务是判断是否有一条从节点 source 出发到节点 destination 的路径存在。

思路:

并查集模板题目

复杂度:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

代码:

import java.util.Scanner;
public class Main{static int[] father;private static boolean isSamed(int a,int b){int x = find(a);int y = find(b);return x==y;}private static void join(int a,int b){int x = find(a);int y = find(b);if(x==y) return;father[y] = father[x];}private static int find(int a){return father[a]==a?a:(father[a]=find(father[a]));}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt()+1;int m = scanner.nextInt();father = new int[n];for(int i=0;i<n;i++)father[i] = i;for(int i=0;i<m;i++){int x = scanner.nextInt();int y = scanner.nextInt();join(x,y);}int source = scanner.nextInt();int destination = scanner.nextInt();System.out.println(isSamed(source,destination)?1:0);}
}

总结

练习了bfs和并查集

往期打卡

代码随想录算法训练营第四十五天

代码随想录算法训练营第四十四天

代码随想录算法训练营第四十二&四十三天

代码随想录算法训练营第四十一天

代码随想录算法训练营第四十天

代码随想录算法训练营第三十九天

代码随想录算法训练营第三十八天

代码随想录算法训练营第三十七天

代码随想录算法训练营第三十五&三十六天

代码随想录算法训练营第三十四天

代码随想录算法训练营第三十三天(补)

代码随想录算法训练营第三十二天

代码随想录算法训练营第三十一天

代码随想录算法训练营第三十天(补)

代码随想录算法训练营第二十九天

代码随想录算法训练营第二十八天

代码随想录算法训练营第二十七天(补)

代码随想录算法训练营第二十六天

代码随想录算法训练营第二十五天

代码随想录算法训练营第二十四天

代码随想录算法训练营第二十三天

代码随想录算法训练营周末四

代码随想录算法训练营第二十二天(补)

代码随想录算法训练营第二十一天

代码随想录算法训练营第二十天

代码随想录算法训练营第十九天

代码随想录算法训练营第十八天

代码随想录算法训练营第十七天

代码随想录算法训练营周末三

代码随想录算法训练营第十六天

代码随想录算法训练营第十五天

代码随想录算法训练营第十四天

代码随想录算法训练营第十三天

代码随想录算法训练营第十二天

代码随想录算法训练营第十一天

代码随想录算法训练营周末二

代码随想录算法训练营第十天

代码随想录算法训练营第九天

代码随想录算法训练营第八天

代码随想录算法训练营第七天

代码随想录算法训练营第六天

代码随想录算法训练营第五天

代码随想录算法训练营周末一

代码随想录算法训练营第四天

代码随想录算法训练营第三天

代码随想录算法训练营第二天

代码随想录算法训练营第一天

http://www.lryc.cn/news/2386053.html

相关文章:

  • 华硕FL8000U加装16G+32G=48G内存条
  • 前后端联调实战指南:Axios拦截器、CORS与JWT身份验证全解析
  • java高级 -Junit单元测试
  • 在 UVM验证环境中,验证 Out-of-Order或 Interleaving机制
  • V9数据库替换授权
  • 勇闯Chromium—— Chromium的多进程架构
  • Go语言中常量的命名规则详解
  • 软件质量保证与测试实验
  • 历年华东师范大学保研上机真题
  • 【C++】什么是静态库?什么是动态库?
  • 项目阅读:Instruction Defense
  • springboot中拦截器配置使用
  • 用 Python 构建自动驾驶的实时通信系统:让车辆“交流”起来!
  • 在机器学习中,L2正则化为什么能够缓过拟合?为何正则化等机制能够使一个“过度拟合训练集”的模型展现出更优的泛化性能?正则化
  • day36 python神经网络训练
  • k8s部署ELK补充篇:kubernetes-event-exporter收集Kubernetes集群中的事件
  • 【Excel VBA 】窗体控件分类
  • C++性能相关的部分内容
  • Spring Boot 项目中常用的 ORM 框架 (JPA/Hibernate) 在性能方面有哪些需要注意的点?
  • 基于大模型的大肠癌全流程预测与诊疗方案研究报告
  • 解决DeepSeek部署难题:提升效率与稳定性的关键策略
  • AI进行提问、改写、生图、联网搜索资料,嘎嘎方便!
  • GStreamer开发笔记(四):ubuntu搭建GStreamer基础开发环境以及基础Demo
  • 2021年认证杯SPSSPRO杯数学建模A题(第二阶段)医学图像的配准全过程文档及程序
  • CV中常用Backbone-3:Clip/SAM原理以及代码操作
  • RPC 协议详解、案例分析与应用场景
  • dify-plugin-daemon的.env配置文件
  • 【Python】开发工具uv
  • 《技术择时,价值择股》速读笔记
  • Python可视化设计原则