沿着一维阵列移动

时间:2016-03-14 23:50:39

标签: arrays algorithm iteration permutation

我最近在网上编码挑战中遇到过这个问题,但我似乎没有任何头脑。

有一个由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;
    }

4 个答案:

答案 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解决方案。

这是一种递归方法。我创建了一个帮助函数,它将currentIndxarrayjumpValueSet of visited indices作为参数。

由于currentIndx不能&lt; 0,我返回false; 如果currentIndx&gt; arr.length - 1,我们完成了。 如果currentIndx的值不为0,则我们必须再次返回false,因为它不在路径中。

现在,在这些检查之后,我们将访问的索引添加到集合中。如果add操作返回false,则必须先访问该索引;所以我们返回false。

然后,我们递归。我们使用currentIndx - 1currentIndx + 1currentIndx + jumpValue调用相同的函数来查看它返回的内容。如果其中任何一个都是真的,我们就找到了一条路径。

[Java source code]

答案 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;
}