简体   繁体   中英

Java Puzzle moving left and right in an array of integers

I have an array of integers. Starting from the first position, I then add or subtract the value at the given index to move around in the array. The purpose of the puzzle is to get to the last element of the array which is 0. I'm aware that this problem is already solved here with recursion, but I'm supposed to give a non-recursive solution. To avoid an infinite loop, I make a condition

if (a[index] == a[index+temp]) 

and the code works fine when I pass an array like this:

int a [] = { 3, 1, 2, 3, 0 };

But then I pass int a [] = {3, 6, 4, 3, 3, 4, 3, 5, 3, 0 } and it tells me that the puzzle does not have a solution, which is not true. Here is part of my code:

       int temp;
       int index = 0;

       while (index < (a.length-1) && index >= 0)
            {
                temp = a[index];

                if ((index+temp) <= a.length-1 )
                {
                    if (a[index] == a[index+temp]){
                        solution = false;
                        break;
                    }
                    index = index + temp;
                }
                else if ((index-temp) >=0)
                {

                    index = index - temp;
                }

        }   

I attach a photo from my assignment which explains the behavior of the algorithm. 在此处输入图片说明

What you have here is basically a directed unweighted graph. Each index is connected with 1 or 2 other indexes.

Now, having that in mind, you can solve this problem easily with a " breadth first search " algorithm which works pretty well without recursion.

Here is pretty verbose implementation example: https://ideone.com/yzeBzz

List<Integer> solve(int... a) {
    //Value in each element is the index, from where we can come here
    int[] path = new int[a.length];
    Arrays.fill(path, -1); //No index is accessible yet

    //Queue of positions that were visited from somewhere, but nothing was tried to be 
    //visited from them. At the beginning, 0 is in the list, because it's starting point.
    //Then, if we visit index 3, it is added to this list for later processing.
    Queue<Integer> posQueue = new LinkedList<>();
    posQueue.add(0);
    path[0] = 0; //0 index is accessible from itself, this is starting position

    while (!posQueue.isEmpty()) {
        int pos = posQueue.remove();
        int prPos = pos - a[pos];
        int nxPos = pos + a[pos];
        if (prPos >= 0 && path[prPos] == -1) {
            path[prPos] = pos;
            posQueue.add(prPos);
        }
        if (nxPos < a.length && path[nxPos] == -1) {
            path[nxPos] = pos;
            posQueue.add(nxPos);
        }

        if (path[a.length-1] != -1) {
            break;
        }
    }

    if (path[a.length-1] == -1) {
        return null;
    }

    //Collect the path
    List<Integer> result = new ArrayList<>();
    int idx = a.length-1;
    while (idx != 0) {
        result.add(0, idx);
        idx = path[idx];
    }
    result.add(0, 0);
    return result;
}

As with any breadth search algorithm, the complexity is O(N).

This might work:

boolean solve(int... a) {
    for (int i = 0; i < 1 << a.length; i++) {
        int pos = 0;
        for (int j = 0; j < 32; j++) {
            if ((i & (1 << j)) == 0) {
                if ((pos -= a[pos]) < 0) {
                    break;
                }
            } else {
                if ((pos += a[pos]) >= a.length) {
                    break;
                }
            }
            if (a[pos] == 0) {
                return true;
            }
        }
    }
    return false;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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