力扣-省份数量

思路分析

用队列实现非递归遍历,从未访问的城市入队,依次取出并标记其连通城市入队,队列为空时完成一个省份的遍历。

代码实现

java 复制代码
public int findCircleNum(int[][] isConnected) {
    // 城市数量
    int n = isConnected.length;
    // 访问标记数组,用于记录每个城市是否被访问过
    boolean[] visited = new boolean[n];
    // 定义队列用于bfs遍历
    Deque<Integer> queue = new LinkedList<>();
    // 定义相连的城市数量
    int provinceCount = 0;
    // 遍历所有城市
    for (int i = 0; i < n; i++) {
        // 若该城市未被访问过
        if (!visited[i]){
            // 标记被访问过
            visited[i] = true;
            // 该城市入队列
            queue.offer(i);
            // bfs遍历所有与该城市相连的城市
            while(!queue.isEmpty()){
                // 队首元素出队列
                Integer pop = queue.pop();
                for (int j = 0; j < n; j++) {
                    // 若该城市未被访问过且与当前城市相连
                    if (!visited[j] && isConnected[pop][j] == 1){
                        // 标记被访问过
                        visited[j] = true;
                        // 该城市入队列
                        queue.offer(j);
                    }
                }
            }
            // 遍历完所有与该城市相连的城市后,相连的城市数量加1
            provinceCount++;
        }
    }

    return provinceCount;
}

复杂度分析

  • 时间复杂度:O(n2)(遍历整个矩阵);
  • 空间复杂度:O(n)(visited 数组 + 队列,最坏情况队列存储所有城市)。

与树的bfs算法对比

这里贴出bfs算法,方便自己理解该题

java 复制代码
// 按层输出:返回二维列表,每个子列表对应一层的节点值
 public List<List<Integer>> levelOrder(TreeNode root) {
     List<List<Integer>> result = new ArrayList<>();
     if (root == null) return result;

     Queue<TreeNode> queue = new LinkedList<>();
     queue.offer(root);

     while (!queue.isEmpty()) {
         int levelSize = queue.size(); // 关键:当前层的节点数
         List<Integer> currentLevel = new ArrayList<>();

         // 遍历当前层的所有节点
         for (int i = 0; i < levelSize; i++) {
             TreeNode curr = queue.poll();
             currentLevel.add(curr.val);

             // 子节点入队(为下一层准备)
             if (curr.left != null) queue.offer(curr.left);
             if (curr.right != null) queue.offer(curr.right);
         }
         result.add(currentLevel); // 将当前层加入结果
     }
     return result;
 }

首先

  1. 二叉树的层次遍历中,根节点只有一个,所以直接就是
java 复制代码
 queue.offer(root);

 while (!queue.isEmpty()) {
 ....
 }

而本题中,多个城市相当于有多个节点,所以多了一层for循环,即第一层for循环

java 复制代码
  for (int i = 0; i < n; i++) {
  ...
  }
  1. 其次,树的层次遍历中,遍历的次数是该层的节点数,也就是
java 复制代码
for (int i = 0; i < levelSize; i++) {
	...
}

而本题中,每层的节点数都是固定也,因为题目说了是n*n的矩阵,也就是说每层都有n个节点,所以第二层循环要执行n次,也就是

java 复制代码
for (int j = 0; j < n; j++) {
...
}
相关推荐
一方热衷.36 分钟前
YOLO26-Seg ONNXruntime C++/python推理
开发语言·c++·python
YMWM_2 小时前
如何将包路径添加到conda环境lerobot的python路径中呢?
人工智能·python·conda
炽烈小老头2 小时前
【每天学习一点算法 2026/03/08】相交链表
学习·算法·链表
田里的水稻2 小时前
ubuntu22.04_openclaw_ROS2
人工智能·python·机器人
一碗白开水一2 小时前
【工具相关】OpenClaw 配置使用飞书:打造智能飞书助手全流程指南(亲测有效,放心享用)
人工智能·深度学习·算法·飞书
梁正雄2 小时前
Python前端-2-css练习
前端·css·python
仰泳的熊猫3 小时前
题目2194:蓝桥杯2018年第九届真题-递增三元组
数据结构·c++·算法
wefly20173 小时前
开发者效率神器!jsontop.cn一站式工具集,覆盖开发全流程高频需求
前端·后端·python·django·flask·前端开发工具·后端开发工具
Tisfy3 小时前
LeetCode 1888.使二进制字符串字符交替的最少反转次数:前缀和O(1)
算法·leetcode·字符串·题解
6+h3 小时前
【java】基本数据类型与包装类:拆箱装箱机制
java·开发语言·python