我最近在网上编码挑战中遇到过这个问题,但我似乎没有任何头脑。
有一个由0和1组成的一维数组。
玩家从索引0开始,需要超出数组的长度。
一旦超过阵列的长度,玩家就会获胜。
玩家只能进入有0的索引。
玩家可以向后移动1步,向前移动1步或向前移动数步。
问题是如何确定游戏是否可以获胜。
这一切归结为以下函数签名:
boolean winnable(int[] arr, int m){
}
有人可以帮助我使用算法来开始。
稍后添加
我可以使用这个算法,当然这个算法并没有通过大多数测试用例。
public static boolean winnable(int[] arr, int m){
int currPos = 0;
for(int i=1; i< arr.length; i++){
if(currPos == arr.length -1 - m) return true;
else if(arr[i] == 0)currPos++;
else if(arr[i] == 1){
if(arr[currPos + m] == 0) currPos = currPos + m;
}
}
return false;
}
答案 0 :(得分:2)
迭代整个数组。对于每个单元格 - &gt; 如果为1,则将其标记为无法访问。否则,检查是否可以到达。如果有,则可以访问单元格 A)可达之前的单元格 B)细胞m细胞可以到达之前。
一旦单元格被标记为可达,您还必须在其后面标记所有连续的单元格,这些单元格都是&#39; 0&#39;可达。一旦您将一个小于m个单元格的单元格标记为可达,则表示结束可达。如果您已将最后m个单元格标记为无法访问,则无法访问结尾。
答案 1 :(得分:1)
您需要一个队列或其他方式来记住需要检查哪些索引。每次达到之前未见过的零时,您需要检查3个索引:前一个,后一个和距离m
的索引。
队列的大小限制为输入数组中的零个数。例如,如果输入数组有10个零,则队列中可能包含10个以上的项。因此,您可以将队列实现为一个与输入数组大小相同的简单数组。
这里有一些伪代码,展示了如何解决问题:
writeToQueue(0)
while ( queue is not empty )
{
index = readFromQueue
if ( index >= length-m )
the game is winnable
array[index] = 1 // mark this index as visited
if ( index > 0 && array[index-1] == 0 ) // 1 step back
writeToQueue(index-1)
if ( array[index+1] == 0 ) // 1 step forward
writeToQueue(index+1)
if ( array[index+m] == 0 ) // m steps forward
writeToQueue(index+m)
}
if the queue empties without reaching the end, the game is not winnable
请注意,输入数组用于跟踪已访问的索引,即找到的每个0
更改为1
,直到游戏获胜或不再0到达。
答案 2 :(得分:0)
我刚刚在HackerRank上为此问题添加了accepted
解决方案。
这是一种递归方法。我创建了一个帮助函数,它将currentIndx
,array
,jumpValue
和Set of visited indices
作为参数。
由于currentIndx
不能&lt; 0,我返回false;
如果currentIndx
&gt; arr.length - 1,我们完成了。
如果currentIndx
的值不为0,则我们必须再次返回false,因为它不在路径中。
现在,在这些检查之后,我们将访问的索引添加到集合中。如果add操作返回false,则必须先访问该索引;所以我们返回false。
然后,我们递归。我们使用currentIndx - 1
,currentIndx + 1
和currentIndx + jumpValue
调用相同的函数来查看它返回的内容。如果其中任何一个都是真的,我们就找到了一条路径。
答案 3 :(得分:0)
可以使用BFS彻底解决。这是我的解决方案:
private static boolean isReachable(int[] array, int m) {
boolean[] visited = new boolean[array.length];
Queue<Integer> queue = new LinkedList<>();
queue.add(0);
visited[0] = true;
while (!queue.isEmpty()) {
Integer current = queue.poll();
if (current+m >= array.length) {
return true;
} else if (current+m < array.length && array[current+m] == 0 && !visited[current+m]) {
queue.add(current+m);
visited[current+m] = true;
}
if (current+1 >= array.length) {
return true;
} else if (current+1 < array.length && array[current+1] == 0 && !visited[current+1]) {
queue.add(current+1);
visited[current+1] = true;
}
if (current-1 >= 0 && array[current-1] == 0 && !visited[current-1]) {
queue.add(current-1);
visited[current-1] = true;
}
}
return false;
}