繁体   English   中英

在HackerRack的道路和图书馆中超时

[英]Time out in Roads and Libraries on HackerRack

我已经研究了HackerRank这个问题已有一段时间了,我似乎无法理解为什么我的代码因输入大而超时。 我已经将邻接表实现为Hash映射以减少时间,并且一直在为我的DFS使用堆栈,这是优化其运行时间的标准。 我这里的基本策略是使用DFS删除一组连接的节点,并继续执行此操作,直到没有节点为止(我的DFS删除了到达的节点),问题是我执行完每个图之后,通常每个图表有〜80,000个断开的部分取出没有邻居的单个节点(因此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的文件。

通常,您正在执行的操作很接近, HashMap<Integer, List<Integer>>是完成此任务的良好数据结构。 但是,您要通过保留explored列表以及从numDisconnecteddepthFirstSearch (在问题的早期版本中)中的邻接图中删除来完成多余的工作。 这些中的任何一个都应该足以实施深度优先搜索。

我不是从形容词删除,变更调整了你的算法explored为布尔[]和使用探索出一条断开的组成部分,并寻找下一个节点从当组件完成启动DFS。

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

(很抱歉改写而不是发布代码,但我不想破坏它)

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

通过了HackerRankRoads and Libraries挑战中的所有测试:

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));
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM