到达终点的最小移动次数

Minimum Number of move to reach End

我需要计算用 dice throw Array Value 到达数组末尾的最少跳转次数 Array Value may be negative/positive value:

数组中可能还包含R值,即玩家必须再次掷骰子

开始位置在我们的Array上用S标记,结束位置用E标记开始位置并不总是Array的第一个元素,结束位置也不总是在末尾,甚至可以在S之前

示例:数组 = {4, S, -2,1, R, 4,3,4,3,-5,2,-4, E}

玩家从 S 位置开始到达 E 的最快方式:

所以这个例子的最佳解决方案是:3 步

让我们给你一个提示:这里要学习的关键是:有时你必须转换输入数据才能找到解决问题的好方法。

在你的情况下;考虑将您的数组转换为图表:

  • 每个数组索引都是该图中的一个节点
  • 每个数组位置的值告诉您一些关于其他节点的边的信息。例如,如果 a(0) 是 R;那么 a(0) 将连接到 a(1)、a(2) .. a(6) - 因为您可以到达接下来的 6 个元素。

初学者;我建议手动执行此操作;只需为示例数组绘制图形。

所以,解决您问题的步骤:

  1. 将数组转换为图形
  2. 在网上搜索算法以在图中查找最小长度路径
  3. 打印出那个路径;导致从 S 到 E
  4. 的最小列表

实施留作 reader 的练习。

我写了这个可行的解决方案,我将它分享给任何感兴趣的人,但是当涉及到处理大数组(例如 3000)时,它会抛出一个 java 堆 space错误,因为代码会消耗大量内存,任何帮助或建议将不胜感激

public class Solution {
static int startPosition;


public static int compute(BufferedReader br) throws IOException {
    final int totalNodeCount = getTotalNodeNumber(br);
    final String caseArray[] = new String[totalNodeCount];
    bufferToArray(br, caseArray);
    startPosition = getStartPosition(caseArray);
    final boolean visited[] = new boolean[caseArray.length];
    int minimumNumberOfMove = 0;
    final List<Integer> reachableList = new ArrayList<Integer>();


    for (int i = 1; i <= 6; i++) 
    {
        visitedInitilise(visited);
        if (((startPosition + i) < totalNodeCount) && ((startPosition + i) > 0))
            getMinimumNumberOfMoves(caseArray, visited, startPosition + i, 0, reachableList);
    }

    // Retriving Minimum number of move from all reachble route
    if (reachableList.isEmpty())
        minimumNumberOfMove = Constants.IMPOSSIBLE;
    else

    {
        minimumNumberOfMove = reachableList.get(0);
        for (int i = 0; i < reachableList.size(); i++)
            if (reachableList.get(i) < minimumNumberOfMove)
                minimumNumberOfMove = reachableList.get(i);

    }

    return minimumNumberOfMove;

}


static int getStartPosition(String[] plateau){

    int startIndex = 0;
    for (int i = 0; i <= (plateau.length - 1); i++)
        if (plateau[i].equals("S")) 
        {
            startIndex = i;
            break;
        }

    return startIndex;
}
static void bufferToArray(BufferedReader br, String[] plateau) {
    String line;
    int i = 0;
    try 
    {
        while ((line = br.readLine()) != null)
        {
            plateau[i] = line;
            i++;
        }
    }
    catch (IOException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


static int getTotalNodeNumber(BufferedReader br) {
    int i = 0;
    try 
    {
        i = Integer.parseInt(br.readLine());
    } catch (NumberFormatException e) 
    {
        e.printStackTrace();
    } catch (IOException e) 
    {
        e.printStackTrace();
    }
    return i;
}
static List<Integer> getMinimumNumberOfMoves(String[] plateau, boolean[] visited, final int currentIndex,
        int currentNumberOfMoves, List<Integer> list) {

    Boolean endIsReached = false;
    Boolean impossible = false;
    visited[startPosition] = true;
    // Checking if the current index index is negativ
    if (currentIndex < 0)
        impossible = true;

    while ((endIsReached == false) && (impossible == false) && (visited[currentIndex] == false)
            && (currentIndex < plateau.length)) 
    {
        try 
        {

            switch (plateau[currentIndex]) {
            case "E": {
                // if end is reached , pushing number of move into our list
                endIsReached = true;
                list.add(currentNumberOfMoves + 1);
                break;

            }

            case "R": {
                // Marking node as visited
                visited[currentIndex] = true;

                for (int i = 1; i <= 6; i++) 
                {
                    // Marking all case after R case as non visited
                    for (int j = currentIndex + 1; j < visited.length; j++)
                        visited[j] = false;
                    // Calculating number of move after R case
                    if (((currentIndex + i) < plateau.length) && (currentIndex > 0))
                        getMinimumNumberOfMoves(plateau, visited, currentIndex + i, currentNumberOfMoves + 1, list);
                }

                break;
            }
            default: {
                // Cheking if node was already visited
                if (visited[currentIndex] == true) 
                {
                    // Marking all node as non visited
                    visitedInitilise(visited);

                    impossible = true;
                    break;
                } 
                else 
                {
                    // when the node was not visited before , catch the jump
                    // value
                    int jumpValue = Integer.parseInt(plateau[currentIndex]);
                    // cheking that the next node is not bigger than node
                    // number and not negativ
                    if (((currentIndex + jumpValue) > plateau.length) || (currentIndex < 0)) 
                    {
                        impossible = true;
                        break;
                    } 
                    else 
                    {
                        // Marking node as visited
                        visited[currentIndex] = true;
                        // calculating minimum number of move starting from
                        // this node
                        getMinimumNumberOfMoves(plateau, visited, currentIndex + jumpValue,
                                currentNumberOfMoves + 1, list);
                        break;
                    }
                }

            }

            }

        } 
        catch (NumberFormatException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        break;
    }
    if (impossible == true)
        currentNumberOfMoves = 0;

    return list;

}

static void visitedInitilise(boolean visited[]) {

        for (int i = 0; i <= (visited.length - 1); i++)
            visited[i] = false;
    }

public static void main(String args[]){
    String testCaseID = "15"; // Write a test file number from 1 to 15, or
                                // ALL
    TestCases.test(testCaseID);
}

}