- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
因此,Hackerrank 上的一项名为“无环图”的编程竞赛提出了这个挑战,它基本上归结为计算从“有向无环图”中的每个 Node 可到达的 Node 数。例如,假设您有这样的图表:
[ 1 ] ---->[ 2 ]--->[ 4 ]--->[ 5 ]
[ 3 ] ------/
可达性计数(包括源 Node ):
Node 1: 4
Node 2: 3
Node 3: 4
Node 4: 2
Node 5: 1
我的方法是使用内存的“深度优先”遍历。环顾四周,但由于在这种情况下发生的过度计数,运行时间似乎无法进一步改进:
[ 1 ] ---->[ 2 ]--->[ 4 ]--->[ 5 ]
[ 3 ] ------/--------/
第三个 Node 将计算第四个 Node ,即使第二个 Node 已经计算了第四个 Node 。更糟糕的是,我只用 JavaScript 解决了这些挑战。它是我的主要语言,我从突破它的界限中得到了快感。排行榜上还没有人用 JavaScript 解决它,但我认为这是可能的。比赛结束后,我成功通过了 24 个测试用例中的 13 个,代码如下:
function Solution( graph, nodes ) {
var memory = new Array( nodes + 1 )
, result = 0;
graph.forEach( ( a, v ) => DepthFirstSearch( graph, v, memory ) );
// challenge asks for an output variation, but the accurate
// reachability count of every node will be contained in "d.length".
memory.forEach( ( d, i ) => { if ( i && ( 2 * d.length ) >= nodes ) result++; } );
return result;
}
function DepthFirstSearch( graph, v, memory ) {
if ( memory[ v ] ) return memory[ v ];
var descendants = new Uint16Array( [ v ] );
graph[ v ].forEach( u => {
descendants = MergeTypedArrays(
DepthFirstSearch( graph, u, memory ),
descendants
);
} );
// make elements unique
// to avoid over counting
return memory[ v ] = Uint16Array.from( new Set( descendants ) );
}
function MergeTypedArrays(a, b) {
var c = new a.constructor( a.length + b.length );
c.set( a );
c.set( b, a.length );
return c;
}
// adjacency list
var graph = [
[], // 0
[ 2 ], // 1
[ 4 ], // 2
[ 2 ], // 3
[ 5 ], // 4
[] // 5
];
var nodes = 5;
Solution( graph, nodes );
对于所有大于 50kb 的输入,它都失败了,可能是具有大量 Node 和边的输入(即 50,000 个 Node 和 40,000 个边)。由于未能确定或构思出一种更快、内存效率更高的算法,我完全不知道接下来要尝试什么。考虑过使 DFS 迭代,但我认为内存数千个数组的内存消耗将使它相形见绌,这似乎是主要问题。对于失败的 11 个测试(与“超时”相对),我在 Hackerrank 上收到“Abort Called”和“Runtime Error”。还尝试了“bitSets”和“union”,但内存消耗变得更糟,因为 bitSets 数组需要足够大才能存储最多 50,000 个数字。
约束:
1 ≤ n,m ≤ 5×10^4
1 ≤ a(i),b(i) ≤ n and a(i) ≠ b(i)
It is guaranteed that graph G does not contain cycles.
只是想说清楚,因为这个挑战是锁定的,所以我不会因为通过所有测试而获得任何积分,这是出于教育目的,主要是优化。我知道指向拓扑排序的相关 SO 帖子,但据我了解,拓扑排序仍然会在上述情况下过度计算,因此不是可行的解决方案。如果我理解有误,请赐教。提前感谢您的宝贵时间。
问题:如何进一步优化它?有没有更有效的方法?
最佳答案
深度优先搜索 (DFS) 是解决此问题的一种好方法。另一种方法是广度优先搜索 (BFS),它也可以并行运行并且可以很好地优化 - 但所有这些都以更高的代码复杂性为代价。所以我的建议是坚持使用 DFS。
首先我要道歉,但我的 JavaScript 技能不是很好(即它们不存在)所以我下面的解决方案是使用 Java 但这些想法应该很容易移植。
你最初的问题遗漏了一个非常重要的细节:我们只需要找到所有可达 Node 数大于或等于 |V| 的 Node 。/2
为什么这很重要?计算每个 Node 的可达 Node 数非常昂贵,因为我们必须从图中的每个 Node 开始进行 DFS 或 BFS。但是如果我们只需要找到具有上述属性的 Node ,那就容易多了。
设 successors(n) 是从 n 可达的所有 Node ,ancestor(n) 是可以到达 n 的所有 Node 。我们可以使用以下观察结果来大幅减少搜索空间:
我们如何使用它?
false
初始化它>= |V|/2
(见下文)使用迭代 DFS 的解决方案
public int countReachable(int root, boolean[] visited, boolean[] ignored, Graph graph) {
if (ignored[root]) {
return 0;
}
Stack<Integer> stack = new Stack<>();
stack.push(root);
int count = 0;
while (stack.empty() == false) {
int node = stack.pop();
if (visited[node] == false) {
count++;
visited[node] = true;
for (int neighbor : graph.getNeighbors(node)) {
if (visited[neighbor] == false) {
stack.push(neighbor);
}
}
}
}
if (count * 2 >= graph.numNodes()) {
return markAndCountAncestors(root, visited, ignored, graph);
} else {
return markSuccessors(root, visited, ignored, graph);
}
}
标记祖先的功能
这只是另一个 DFS,但使用了转置图。请注意,我们可以重用 visited
数组,因为我们将使用的所有值都是 false
,因为这是一个非循环图。
public int markAndCountAncestors(int root, boolean[] visited, boolean[] ignored, Graph graph) {
Stack<Integer> stack = new Stack<>();
stack.push(root);
visited[root] = false;
int count = 0;
while (stack.empty() == false) {
int node = stack.pop();
if (visited[node] == false && ignored[node] == false) {
count++;
visited[node] = true;
ignored[node] = true;
for (int neighbor : graph.transposed.getNeighbors(node)) {
if (visited[neighbor] == false && ignored[node] == false) {
stack.push(neighbor);
}
}
}
}
return count;
}
标示接类人的功能
请注意,我们已经有了后继者,因为它们只是我们将 visited
设置为 true 的 Node 。
public int markSuccessors(int root, boolean[] visited, boolean[] ignored, Graph graph) {
for(int node = 0; node < graph.numNodes(); node++) {
if (visited[node)) {
ignored[node] = true;
}
}
return 0;
}
计算结果的函数
public void solve(Graph graph) {
int count = 0;
boolean[] visited = new boolean[graph.numNodes()];
boolean[] ignored = new boolean[graph.numNodes()];
for (int node = 0; node < graph.numNodes(); node++) {
Arrays.fill(visited, false); // reset visited array
count += countReachable(node, visited, ignored, graph);
}
System.out.println("Result: " + count);
}
在您发布的大型测试用例中,我的运行时间为 7.5 秒。如果你反转迭代顺序(即在 solve
中你从最大的 Node id 开始)它会下降到 4 秒,但这有点像作弊 ^^
关于javascript - 有向无环图中所有 Node 的可达性计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35829819/
我正在尝试通过可访问性来覆盖我的基础,以便我的应用程序不会被应用程序商店拒绝。我熟悉 Apple 在示例代码中提供的 Reachability 类。我的问题是,如何最好地实现这一点。我发现检查 WWA
我有一个 TableView,它使用方法调用 retrieveData 从服务器接收数据。我使用 Reachability 来测试用户是否有互联网连接。如果是,则调用 retrieveData。如果不
一个简单的问题:当应用程序被终止或未运行时,是否可以在互联网连接可用时收到消息、通知或类似信息? 出于我的目的,我需要一种方法来同步我的所有通知,因为 APNs 只能发送最后一条消息。 编辑:我想知道
我终于弄明白了如何使用 apple Reachability 文件,这是一件了不起的事情。 我的问题是,因为我有大约 6 个 View ,每个 View 都需要检查我是否已连接到互联网。在我的应用程序
我正在使用 Apple 提供的示例代码来监控可达性 - 但它仍然让我头疼。顺便说一句,我在 iOS 5 上运行。 // Initialise hostReach = [[Reachability re
Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"]; 这条线在设备上运行良好,但在模拟器上我崩溃了:
在我的应用程序中的 appDelegate.m 中,我插入了可达性代码,就像苹果说的那样: -(BOOL)checkInternet { Reachability *r = [Reachability
大家好,我在使用 Apple 的可达性代码时遇到了一些问题。我发现,即使设备正确连接到互联网,最初可达性代码也会发出 1 个错误通知(Networkstatus = NotReachable),然后是
我的 AppDelegate.m 中有以下代码 - NSLog 的结果始终是 (null),因此条件没有可达性永远不会被解雇。我想知道为什么会这样/我做错了什么。 - (BOOL)applicatio
我正在使用 github 上的 Reachability 库,发现 here .我想通过单击按钮来检查设备是否在线。我是 Reachability 的新手,所以据我所知,您必须开始监听更改,然后测试连
我正在使用这个库:https://github.com/tonymillion/Reachability 问题有时出现在我检查以下表达式时:[[[ReachabilityManager sharedM
我对 AFNetorking 的 Reachability 有点迷茫,没有找到很多有用的信息。 我有一个可以登录 Web API 的应用程序。每个 VC 都以某种方式连接到 API,因此每个 VC 都
我了解如何在我的应用程序中测试互联网可达性,但我需要做的是不断监听应用程序范围内的可达性。因此,如果应用程序中任何地方的任何一点连接状态发生变化,我都可以使用react。 我怎样才能实现这样的目标?
我正在开发一个使用网络的 iPhone 应用程序。 iPhone 通过 HTTP 请求与我的服务器通信,应该可以在 WiFi 和 3G 上工作。 我目前使用 NSURLConnection initW
我目前正在使用可达性来检测可用的连接。当什么都没有或有良好的连接时,这很有效。但是,如果我的用户在飞机上拥有自己的 wifi 节点,但没有连接到整个互联网怎么办?我的用户将在 wifi 开启的情况下处
我已经创建了一个方法来检查主机是否可达。我从苹果开发者网站下载了 Reachability 类(.h 和 .m)并导入到我的项目中。我已将 NSString 名称作为 URL(主机名)传递。主机名是
我正在使用这个库在设备上的连接状态发生变化时得到通知。我不明白为什么这不起作用!我正在做的正是我在 github 文档中阅读的内容! 当应用程序启动时,会发布通知,但当我打开设置、打开/关闭飞行模式并
我是 iOS 新手,刚开始使用它。我正在尝试实现网络可达性以检测网络何时断开连接以及何时通过使用第三方类恢复。我能够检测到网络丢失,但我无法检测到网络断开连接后何时恢复。我正在使用以下条件来检查工作正
我用了this检查互联网连接 (WiFi\3G) 是否有效的问题。 它工作得很好,但有一个小问题。 当我关闭互联网时,该应用程序会发出互联网已关闭的警报;但是当我再次打开它时,直到连接确实建立起来,它
我的 Reachability 完全按照此 thread 中的建议工作. 我正在使用 open source Reachability .但是我没有使用 block 而是使用通知,因此该过程与 App
我是一名优秀的程序员,十分优秀!