【问题标题】:Time out in Roads and Libraries on HackerRackHackerRank 中的道路和图书馆超时
【发布时间】:2017-07-25 22:04:35
【问题描述】:

我研究这个 HackerRank 问题已经有一段时间了,但我似乎无法理解为什么我的代码会因大输入大小而超时。我已经将邻接列表实现为哈希映射以减少时间,并且一直在为我的 DFS 使用堆栈,这是优化其运行时间的标准。我的基本策略是使用 DFS 删除一组连接节点,并继续这样做直到没有剩余节点(我的 DFS 在到达节点时删除节点),问题是每个图通常有大约 80,000 个断开连接的部分 after 我取出没有邻居的单个节点(因此 DFS 被调用了 80,000 次)。这里有什么特别好的策略吗?

  static int numDisconnected(HashMap<Integer, List<Integer>> adj)  {
    int result = 0;
    List<Integer> iter = new ArrayList<>(adj.keySet());
    for (int k : iter) {
      if (adj.get(k).size() == 0)  {
        adj.remove(k);
        result++;
      }
    }
    HashMap<Integer,Boolean> explored = new HashMap<>();
    for (int i : adj.keySet())  {
      explored.put(i,false);
    }
    while (!adj.keySet().isEmpty())  {
      result++;
      depthFirstSearch(adj,explored);
    }
    return result;
  }

作为参考,我的代码大约需要 1.5 秒才能在我的机器上运行大约 2MB 的文件输入。

【问题讨论】:

  • 我建议您进行一些分析并将有问题的代码缩小到 10 行或更少。如果您这样做后仍然卡住,您可以提出更具体的问题。
  • @JoeC 我现在就去做
  • 一个观察:所有HashMaps 中的键都是连续整数,因此数组可能更有效。 (HackerRank 挑战使用从 1 开始的城市指数,所以一定要减去一个。)

标签: java algorithm graph graph-algorithm


【解决方案1】:

一般来说,你所做的很接近,HashMap&lt;Integer, List&lt;Integer&gt;&gt; 是一个很好的数据结构来完成这项任务。 但是您通过保留explored 列表并从numDisconnecteddepthFirstSearch 中的邻接映射中删除(在您的问题的早期版本中)来做多余的工作。这些中的任何一个都足以实现深度优先搜索。

我调整了您的算法,不从 adj 中删除,将 explored 更改为 boolean[] 并使用它来探索断开连接的组件,并在组件完成后找到下一个节点以启动 DFS。

通过了,不需要去除未连接节点的预处理步骤。

(对不起,我没有发布代码,而是解释一下,但我不想破坏它)

【讨论】:

    【解决方案2】:

    从你的原始代码开始(在这个问题的第一个修订版中),我用ArrayLists 替换了那些HashMaps,用HashSet 代替explored,内联depthFirstSearch(只是为了简单起见,而不是性能),并摆脱了一些感觉像是过早优化的步骤(删除没有邻居的节点,在主循环中提前返回)。

    这通过了Roads and Libraries challenge on HackerRank 中的所有测试:

    import java.io.*;
    import java.util.*;
    
    public class Solution {
        static long cost(long cLib, long cRoad, ArrayList<List<Integer>> g, int gSize)  {
            if (cLib <= cRoad)  {
                return cLib * (long)gSize;
            }
            int discon = numDisconnected(g);
            return (cRoad * (gSize - discon)) + (cLib * discon);
        }
    
        static int numDisconnected(ArrayList<List<Integer>> adj)  {
            int result = 0;
            HashSet<Integer> explored = new HashSet<>();
            int length = adj.size();
            for (int i = 0; i < length; i++) {
                if (!explored.contains(i)) {
                    Stack<Integer> stack = new Stack<>();
                    stack.push(i);
                    while (!stack.empty()) {
                        int curr = stack.pop();
                        explored.add(curr);
                        for (int neighbor : adj.get(curr)) {
                            if (!explored.contains(neighbor)) {
                                stack.push(neighbor);
                            }
                        }
                    }
    
                    result += 1;
                }
            }
            return result;
        }
    
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            int q = in.nextInt();
            for(int a0 = 0; a0 < q; a0++){
                int nCities = in.nextInt();
                ArrayList<List<Integer>> adj = new ArrayList<List<Integer>>(nCities);
                for (int i = 0; i < nCities; i++) {
                    adj.add(new ArrayList<Integer>());
                }
                int nRoads = in.nextInt();
                long cLib = in.nextLong();
                long cRoad = in.nextLong();
                for (int i = 0; i < nRoads; i++) {
                    int city_1 = in.nextInt() - 1;
                    int city_2 = in.nextInt() - 1;
                    adj.get(city_1).add(city_2);
                    adj.get(city_2).add(city_1);
                }
                System.out.println(cost(cLib, cRoad, adj, nCities));
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-11-05
      • 1970-01-01
      • 2016-02-05
      • 1970-01-01
      • 1970-01-01
      • 2022-07-20
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      相关资源
      最近更新 更多