程序员的算法趣题:Q49 欲速则不达(Java版)

题目要求

题目链接(力扣网):https://leetcode-cn.com/leetbook/read/interesting-algorithm-puzzles-for-programmers/9iftw2/

5*6网格

A点(左上)到B点(右下)

1.只能沿着网格的边移动

2.一步走一格的距离

3.一条直线上的移动步数不超过2步

4.允许路线交叉,允许折返,折返时步数是累加的

求:从A点到B点最多走多少步

思路

程序员的算法趣题:Q49 欲速则不达(Java版)_第1张图片 Q49 欲速则不达

1.用(x,y)表示当前所在的位置

2.用h[]数组表示每条横线上的移动步数

3.用v[]数组表示每条竖线上的移动步数

4.每次移动时只需要考虑当下还可以往哪里移动(不超边界,不超直线上步数的限制)——递归

5.到达B点时,输出一次移动的轨迹

6.统计所有轨迹中最长的值,就是最终结果

代码

public static int max = 0; // 记录最大步数
public static void main(String[] args) {
    int width = 6; // 宽度6格
    int height = 5; // 高度5格
    int[] h = new int[height + 1]; // 横着6条直线,每条直线上移动的步数(<=2)
    int[] v = new int[width + 1];  // 竖着7条直线,每条直线上移动的步数(<=2)
    move(0, 0, h, v, new LinkedList()); // 从A点(0,0)开始
    System.out.println("max = " + max);
}
/**
 * (x,y)表示当前所在的位置,所在的横线为h[y],竖线为v[x]
 * @param list 记录了每一次的移动方向(上、下、左、右)
 */
public static void move(int x, int y, int[] h, int[] v, List list) {
    // 到达B点视为递归出口
    if (x == v.length - 1 && y == h.length - 1) {
        System.out.println("总步数:" + list.size() + "\t" + list);
        max = list.size() > max ? list.size() : max;
        return;
    }

    // 递归调用:可以尝试进行上、下、左、右四个方向的移动
    // 尝试上移
    if (y - 1 >= 0 && v[x] < 2) { // 上移不超边界、直线上移动的总步数不超过限制(2步)
        v[x]++; // 该直线上的移动步数+1
        list.add("上"); // 记录本次的移动方向
        move(x, y - 1, h, v, list); // 上移,并继续进行后续移动...递归
        list.remove(list.size()-1); // 恢复本次递归前的移动轨迹
        v[x] --; // 恢复本次递归前的直线移动步数的统计
    }
    // 尝试下移
    if (y + 1 <= h.length - 1 && v[x] < 2) {
        v[x]++;
        list.add("下");
        move(x, y + 1, h, v, list);
        list.remove(list.size()-1);
        v[x] --;
    }
    // 尝试左移
    if (x - 1 >= 0 && h[y] < 2) {
        h[y]++;
        list.add("左");
        move(x - 1, y, h, v, list);
        list.remove(list.size()-1);
        h[y]--;
    }
    // 尝试右移
    if (x + 1 <= v.length - 1 && h[y] < 2) {
        h[y]++;
        list.add("右");
        move(x + 1, y, h, v, list);
        list.remove(list.size()-1);
        h[y]--;
    }
    
    // 无路可走的情况
}

结果

......此处省略一部分记录......
总步数:13    [右, 右, 下, 右, 下, 左, 下, 右, 右, 下, 右, 右, 下]
总步数:23    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 上, 右, 下, 右, 下, 右, 上, 下, 右]
总步数:21    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 上, 右, 下, 右, 下, 右, 右]
总步数:23    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 下, 右, 上, 右, 上, 右, 下, 下, 右]
总步数:25    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 下, 右, 上, 右, 下, 右, 上, 上, 右, 下, 下]
总步数:23    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 下, 右, 右, 上, 上, 右, 下, 右, 下]
总步数:23    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 下, 右, 右, 上, 右, 上, 右, 下, 下]
总步数:23    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 右, 上, 右, 下, 下, 右, 上, 下, 右]
总步数:21    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 右, 上, 右, 下, 下, 右, 右]
总步数:23    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 右, 下, 右, 上, 上, 右, 下, 下, 右]
总步数:25    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 右, 下, 右, 上, 下, 右, 上, 上, 右, 下, 下]
总步数:23    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 下, 右, 右, 下, 右, 右, 上, 上, 右, 下, 下]
总步数:23    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 右, 下, 右, 下, 右, 上, 下, 右, 上, 右, 下]
总步数:21    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 右, 下, 右, 下, 右, 上, 右, 下, 右]
总步数:21    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 右, 下, 右, 下, 右, 右, 上, 右, 下]
总步数:21    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 右, 下, 右, 右, 下, 右, 上, 下, 右]
总步数:19    [右, 右, 下, 右, 下, 左, 左, 上, 左, 下, 下, 右, 右, 下, 右, 右, 下, 右, 右]
总步数:25    [右, 右, 下, 右, 下, 左, 左, 下, 下, 左, 下, 右, 右, 上, 右, 上, 右, 上, 上, 右, 下, 下, 右, 下, 下]
......此处省略一部分记录......
max = 25
ways = 77970(有这么多条轨迹可以到达B点)

你可能感兴趣的:(力扣,算法,java)