力扣-省份数量

思路分析

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

代码实现

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++) {
...
}
相关推荐
猿儿本无心12 小时前
快速搭建Python项目(Vscode+uv+FastAPI)
vscode·python·uv
智者知已应修善业12 小时前
【51单片机LED闪烁10次数码管显示0-9】2023-12-14
c++·经验分享·笔记·算法·51单片机
智者知已应修善业12 小时前
【51单片机2按键控制1个敞亮LED灯闪烁和熄灭】2023-11-3
c++·经验分享·笔记·算法·51单片机
AI算法沐枫12 小时前
大模型 | 大模型之机器学习基本理论
人工智能·python·神经网络·学习·算法·机器学习·计算机视觉
吃着火锅x唱着歌12 小时前
LeetCode 1019.链表中的下一个更大节点
算法·leetcode·链表
OzupeSir12 小时前
三门两羊问题 - 蒙提霍尔问题
python·概率论
晚霞的不甘12 小时前
CANN asnumpy 深度解析:NPU 原生 NumPy 的使用指南
人工智能·python·numpy
qingfeng1541513 小时前
企业微信 API 自动化开发指南:从消息回调到智能运营实战
java·开发语言·python·自动化·企业微信
凌波粒13 小时前
LeetCode--404.左叶子之和(二叉树)
算法·leetcode·职场和发展