首页 > 其他分享 >【LeetCode 1466】重新规划路线

【LeetCode 1466】重新规划路线

时间:2024-03-15 21:44:05浏览次数:20  
标签:int 城市 已通 路线 ++ canArrive 1466 LeetCode

题目描述

原题链接: LeetCode.1466 重新规划路线

解题思路

  • 路线网形成一棵树, 说明每个节点都参与两条路线, 或作为起点或作为终点;
  • 要想所有城市都可以通往城市0, 必须要把所有逆向的路线都变更一次方向, 逆向路线总数量即为答案;
  • 朴素BFS版本
    • 从城市0出发, 遍历每个从已通城市出发的下一个城市都对应一条需要变更方向的逆向路线, 次数+1然后将归入这些新的已通城市;
    • 再遍历可前往每个已通城市为终点的城市直接纳入已通城市;
    • 直到所有城市编号都已出队, 返回统计到的次数即为答案。
  • 从提交结果图中看到的版本
    • 以路线维度进行遍历, 用boolean数组表示哪些城市编号属于已通城市;
    • 每次遍历路线时, 如果终点属于已通城市那么起点也直接标记为已通城市;
    • 否则再判断起点为已通城市时就是找到了一条需要变更方向的逆向路线, 次数+1然后将终点归入已通城市;
    • 如果起点终点都不属于已通城市, 这条路线保留等待下一轮遍历;
    • 初始化时不需要关心给定的路线顺序, 进行首轮遍历后反复进行一轮轮遍历, 所有路线的起终点均属于已通城市。

解题代码

  • 朴素BFS解法

      /**
       * BFS处理,数组实现队列
       * 执行用时: 34 ms , 在所有 Java 提交中击败了 58.67% 的用户
       * 内存消耗: 67.82 MB , 在所有 Java 提交中击败了 69.70% 的用户
       */
      public int minReorder(int n, int[][] connections) {
          List<Integer>[] toGraph = new List[n];
          List<Integer>[] fromGraph = new List[n];
          for (int i = 0; i < n; i++) {
              toGraph[i] = new ArrayList<>();
              fromGraph[i] = new ArrayList<>();
          }
          for (int[] con : connections) {
              toGraph[con[0]].add(con[1]);
              fromGraph[con[1]].add(con[0]);
          }
          if (toGraph[0].size() == n - 1) {
              return 0;
          }
          int cnt = 0;
          boolean[] visited = new boolean[n];
          int[] queue = new int[n];// 用ArrayDeque的执行用时要慢10ms
          int head = 0, tail = 0;
          queue[tail++] = 0;
          while (tail > head) {
              int c = queue[head++];
              visited[c] = true;
              for (int next : toGraph[c]) {
                  if (!visited[next]) {
                      cnt++;
                      queue[tail++] = next;
                  }
              }
              for (int pre : fromGraph[c]) {
                  if (!visited[pre]) {
                      queue[tail++] = pre;
                  }
              }
          }
          return cnt;
      }
    
  • 以路线维度进行遍历的解法

      /**
       * 从提交结果中复制出来的代码
       * 执行用时: 4 ms , 在所有 Java 提交中击败了 98.87% 的用户
       * 内存消耗: 71.73 MB , 在所有 Java 提交中击败了 13.82% 的用户
       */
      public int minReorder(int n, int[][] connections) {
          int ans = 0;
          boolean[] canArrive = new boolean[n];
          canArrive[0] = true;
          // 记录两端城市都无法到达城市0的路线编号
          List<Integer> list = new ArrayList<>();
          for (int i = 0; i < connections.length; i++) {
              int from = connections[i][0], to = connections[i][1];
              if (canArrive[to]) {// 目的城市能到达,起始城市也可以,直接标记
                  canArrive[from] = true;
              }
              else if (canArrive[from]) {// 起始城市能到达,变更方向后目的城市也能到达,次数+1后标记
                  ans++;
                  canArrive[to] = true;
              }
              else {// 首尾城市都不能到达,待处理
                  list.add(i);
              }
          }
          while (!list.isEmpty()) {// 循环处理直到每个路线首尾两端城市全部可到达
              for (int i = list.size() - 1; i >= 0; i--) {
                  int u = connections[list.get(i)][0];
                  int v = connections[list.get(i)][1];
                  if (canArrive[v]) {
                      canArrive[u] = true;
                      list.remove(i);
                  }
                  else if (canArrive[u]) {
                      ans++;
                      canArrive[v] = true;
                      list.remove(i);
                  }
              }
          }
          return ans;
      }
    

标签:int,城市,已通,路线,++,canArrive,1466,LeetCode
From: https://www.cnblogs.com/coding-memory/p/18076292

相关文章

  • 2024-03-15 leetcode写题记录
    目录2024-03-15leetcode写题记录32.最长有效括号题目链接题意解法42.接雨水题目链接题意解法动态规划双指针2024-03-15leetcode写题记录32.最长有效括号题目链接32.最长有效括号题意给你一个只包含$'\((\)'和'\()\)'的字符串,找出最长有效(格式正确且连续)括号子串的......
  • 【leetcode】二叉树的前序遍历➕中序遍历➕后序遍历
    大家好,我是苏貝,本篇博客带大家刷题,如果你觉得我写的还不错的话,可以给我一个赞......
  • 2024-03-14 leetcode写题记录
    目录2024-03-14leetcode写题记录829.连续整数求和题目链接题意解法2024-03-14leetcode写题记录829.连续整数求和题目链接829.连续整数求和题意给定一个正整数\(n\),返回连续正整数满足所有数字之和为\(n\)的组数。示例1:输入:n=5输出:2解释:5=2+3,共有两......
  • 【小白刷leetcode】第15题
    【小白刷leetcode】第15题动手刷leetcode,正在准备蓝桥,但是本人算法能力一直是硬伤。。。所以做得一直很痛苦。但是不熟练的事情像练吉他一样,就需要慢速,多练。题目描述看这个题目,说实在看的不是很懂。索性我们直接来看输入输出。观察输入输出我们可以知道:输入是一个数......
  • 【LeetCode 2312】卖木头块
    题目描述原题链接:2312卖木头块解题思路每次切割只能完全横切或者竖切,即切成更矮或者更窄的木块;每次切割后剩余的两部分木块都是更小规模的同类问题,典型的可以用动态规划求解的问题;具体到单个问题,高x宽y的木块能卖的最多钱数有三种情况:prices数组中正好有对应宽高的价格......
  • 代码随想录算法训练营第七天|LeetCode 344.反转字符串、541.反转字符串II、卡码网54.替
    344.反转字符串题目描述:​编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间,你必须**原地修改输入数组**、使用O(1)的额外空间解决这一问题。示例一:输入:s=["h","e","l","l","o"]输出:["o","l","l......
  • 新鲜出炉!界面控件DevExpress WinForms 2024产品路线图预览(三)
    DevExpressWinForm拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForm能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!本文将介绍2024年DevExpressWinForms第一个主要更新......
  • 代码随想录训练营第44天 | 动态规划:完全背包理论基础、​​​​​​LeetCode 518.零钱
    目录动态规划:完全背包理论基础文章讲解:代码随想录(programmercarl.com)视频讲解:带你学透完全背包问题!_哔哩哔哩_bilibili思路​​​​​​LeetCode518.零钱兑换II文章讲解:代码随想录(programmercarl.com)视频讲解:518.零钱兑换II_哔哩哔哩_bilibili思路​​​​​​Le......
  • leetcode 2.两数相加 ,链表
    2.两数相加给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字0之外,这两个数都不会以0 开头。 示例1:输入:l1=[2,4......
  • LeetCode题练习与总结:搜索旋转排序数组
    一、题目整数数组nums按升序排列,数组中的值互不相同。在传递给函数之前,nums在预先未知的某个下标k(0<=k<nums.length)上进行了旋转,使数组变为[nums[k],nums[k+1],...,nums[n-1],nums[0],nums[1],...,nums[k-1]](下标从0开始计数)。例如,[0,1,2,4,5,6,7]......