当前位置:   article > 正文

代码随想录Day67(图论 part04)

代码随想录Day67(图论 part04)

110.字符串接龙

题目:110. 字符串接龙 (kamacoder.com)

思路:没有思路

答案
  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner scanner = new Scanner(System.in);
  5. int n = scanner.nextInt();
  6. String beginStr = scanner.next();
  7. String endStr = scanner.next();
  8. Set<String> strSet = new HashSet<>();
  9. for (int i = 0; i < n; i++) {
  10. strSet.add(scanner.next());
  11. }
  12. System.out.println(findShortestTransformation(beginStr, endStr, strSet));
  13. }
  14. private static int findShortestTransformation(String beginStr, String endStr, Set<String> strSet) {
  15. // 记录strSet里的字符串是否被访问过,同时记录路径长度
  16. Map<String, Integer> visitMap = new HashMap<>();
  17. // 初始化队列
  18. Queue<String> queue = new LinkedList<>();
  19. queue.add(beginStr);
  20. // 初始化visitMap
  21. visitMap.put(beginStr, 1);
  22. while (!queue.isEmpty()) {
  23. String word = queue.poll();
  24. int pathLength = visitMap.get(word); // 这个字符串在路径中的长度
  25. // 开始在这个str中,挨个字符去替换
  26. for (int i = 0; i < word.length(); i++) {
  27. char[] newWordArray = word.toCharArray();
  28. // 遍历26个字母
  29. for (char j = 'a'; j <= 'z'; j++) {
  30. newWordArray[i] = j;
  31. String newWord = new String(newWordArray);
  32. if (newWord.equals(endStr)) { // 发现替换字母后,字符串与终点字符串相同
  33. return pathLength + 1; // 找到了路径
  34. }
  35. // 字符串集合里出现了newWord,并且newWord没有被访问过
  36. if (strSet.contains(newWord) && !visitMap.containsKey(newWord)) {
  37. // 添加访问信息,并将新字符串放到队列中
  38. visitMap.put(newWord, pathLength + 1);
  39. queue.add(newWord);
  40. }
  41. }
  42. }
  43. }
  44. // 没找到输出0
  45. return 0;
  46. }
  47. }
小结
  • 使用  Set<String>   存储字符串
  • 使用  Map<String, Integer>  记录是否访问过,以及路径长度
  • 通过queue来存储遍历过的字符串,从beginStr开始,每次替换一个字符,要是替换后的字符串存在于set中,就将该字符串记录为已访问,并将字符串放入到queue中

105.有向图的完全可达性

题目:105. 有向图的完全可达性 (kamacoder.com)

思路:从1出发,进行深搜,走完所有路径,看是否能够到达所有节点

尝试(运行出错)
  1. import java.util.*;
  2. public class Main {
  3. private static List<List<Integer>> adjList;
  4. private static List<List<Integer>> allPaths;
  5. private static int target;
  6. public static void main(String[] args) {
  7. Scanner scanner = new Scanner(System.in);
  8. int n = scanner.nextInt();
  9. int m = scanner.nextInt();
  10. adjList = new ArrayList<>();
  11. for (int i = 0; i < n + 1; i++) {
  12. adjList.add(new ArrayList<>());
  13. }
  14. for (int i = 0; i < m; i++) {
  15. int s = scanner.nextInt();
  16. int t = scanner.nextInt();
  17. adjList.get(s).add(t);
  18. }
  19. for(int i =2; i<=n; i++){
  20. target = i;
  21. allPaths = new ArrayList<>();
  22. List<Integer> currentPath = new ArrayList<>();
  23. currentPath.add(1);
  24. findAllPaths(1, currentPath);
  25. if(allPaths.isEmpty()){
  26. System.out.println("-1");
  27. }
  28. }
  29. System.out.println("1");
  30. scanner.close();
  31. }
  32. private static void findAllPaths(int currentNode, List<Integer> currentPath) {
  33. if (currentNode == target) {
  34. allPaths.add(new ArrayList<>(currentPath));
  35. return;
  36. }
  37. for (int nextNode : adjList.get(currentNode)) {
  38. currentPath.add(nextNode);
  39. findAllPaths(nextNode, currentPath);
  40. currentPath.remove(currentPath.size() - 1);
  41. }
  42. }
  43. }
答案
  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner scanner = new Scanner(System.in);
  5. int n = scanner.nextInt(); // 节点数量
  6. int m = scanner.nextInt(); // 边的数量
  7. // 节点编号从1到n,所以申请 n+1 这么大的数组
  8. List<List<Integer>> graph = new ArrayList<>(n + 1);
  9. for (int i = 0; i <= n; i++) {
  10. graph.add(new ArrayList<>());
  11. }
  12. // 读取边的信息并构建邻接表
  13. for (int i = 0; i < m; i++) {
  14. int s = scanner.nextInt();
  15. int t = scanner.nextInt();
  16. graph.get(s).add(t);
  17. }
  18. // 初始化访问数组
  19. boolean[] visited = new boolean[n + 1];
  20. dfs(graph, 1, visited);
  21. // 检查是否所有节点都被访问到了
  22. for (int i = 1; i <= n; i++) {
  23. if (!visited[i]) {
  24. System.out.println(-1);
  25. return;
  26. }
  27. }
  28. System.out.println(1);
  29. }
  30. private static void dfs(List<List<Integer>> graph, int node, boolean[] visited) {
  31. if (visited[node]) {
  32. return;
  33. }
  34. visited[node] = true;
  35. for (int neighbor : graph.get(node)) {
  36. dfs(graph, neighbor, visited);
  37. }
  38. }
  39. }
小结

通过递归, 把所有路径跑一遍, 之后再检查是否所有的节点都有被访问到, 此处不需要回溯

106.岛屿的周长

题目:106. 岛屿的周长 (kamacoder.com)

思路:逐个遍历1,计算每个1跟临近的0所形成的边界,加起来,就是周长

尝试(示例输出正确,提交后输出错误)
  1. import java.util.*;
  2. class Main{
  3. public static int n;
  4. public static int m;
  5. public static int[][] grid;
  6. public static void main(String[] args){
  7. Scanner scanner = new Scanner(System.in);
  8. n = scanner.nextInt();
  9. m = scanner.nextInt();
  10. grid = new int[n][m];
  11. for(int i=0; i<n; i++){
  12. for(int j=0; j<m; j++){
  13. grid[i][j] = scanner.nextInt();
  14. }
  15. }
  16. int maxArea = 0;
  17. for(int i=0; i<n; i++){
  18. for(int j=0; j<m; j++){
  19. maxArea+=count(i,j);
  20. }
  21. }
  22. System.out.println(maxArea);
  23. }
  24. public static int count(int i,int j){
  25. if(grid[i][j]!=1) return 0;
  26. int len = 0;
  27. if(grid[i-1][j]==0){
  28. len++;
  29. }
  30. if(grid[i+1][j]==0){
  31. len++;
  32. }
  33. if(grid[i][j-1]==0){
  34. len++;
  35. }
  36. if(grid[i][j+1]==0){
  37. len++;
  38. }
  39. return len;
  40. }
  41. }
答案
  1. import java.util.Scanner;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner scanner = new Scanner(System.in);
  5. int n = scanner.nextInt(); // 行数
  6. int m = scanner.nextInt(); // 列数
  7. int[][] grid = new int[n][m];
  8. for (int i = 0; i < n; i++) {
  9. for (int j = 0; j < m; j++) {
  10. grid[i][j] = scanner.nextInt();
  11. }
  12. }
  13. int landCount = 0; // 陆地数量
  14. int neighborCount = 0; // 相邻陆地的数量
  15. for (int i = 0; i < n; i++) {
  16. for (int j = 0; j < m; j++) {
  17. if (grid[i][j] == 1) {
  18. landCount++; // 统计总的陆地数量
  19. // 统计上边相邻陆地
  20. if (i - 1 >= 0 && grid[i - 1][j] == 1) neighborCount++;
  21. // 统计左边相邻陆地
  22. if (j - 1 >= 0 && grid[i][j - 1] == 1) neighborCount++;
  23. // 下边和右边的相邻陆地不统计是为了避免重复计算
  24. }
  25. }
  26. }
  27. // 计算岛屿的周长
  28. int perimeter = landCount * 4 - neighborCount * 2;
  29. System.out.println(perimeter);
  30. }
  31. }
小结

注意每次只统计上边和左边的相邻陆地

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号