【携程2017年笔试题】计算最长奔跑路径长度

来源:互联网 发布:娶网络女主播 编辑:程序博客网 时间:2024/06/11 19:51
 * 题目:Tom猫喜欢从高的地方往低的地方奔跑,现在通过矩阵的方式表示某一区域的高低,
 * 如下所示:
 * 1 2 3 4
 * 12 13 14 5
 * 11 16 15 6
 * 10 9 8 7
 * 可以从矩阵中某一点奔跑到上下左右相邻的较小的点上,例如上面所示的矩阵中一条可以奔跑
 * 的路径为14-13-2-1,长度为4,而最长的路径显然是16-15-14-……-4-3-2-1,长度为16
 * 请计算出最长的奔跑路径的长度
 * 输入:
 * 第一行为两个正整数X和Y(1<=X,Y<=100),然后第二行开始为X*Y的矩阵,包含不同位置的高度H,

 * H也是正整数,且不大于10000。

 * 输出:
 * 最长奔跑长度

解题方法:

  我的方法很简单,时间复杂度也很高,就是按照正常思维来解题没有做任何优化,等我想到更优的解,再来更新。

  第一步,给二维数组的四个边界添加一行或一列且是很大的数,用Integer.MAX_VALUE,防止下面的数组越界;

  第二步,遍历二维数组中以每个数为起点,得到每个数最长奔跑路径长度;

  第三步,递归二维数组求最长奔跑路径,递归的时候最一点小优化,就是用二维数组记录下当前位置已经算好路径长度,下次如果递归到这个位置时,

可以直接返回,不用再递归下去了。

import java.util.ArrayList;import java.util.List;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);while(in.hasNext()){int row = in.nextInt();int col = in.nextInt();int[][] array1 = new int[row+2][col+2];for(int i=1; i<row+1; i++){for(int j=1; j<col+1; j++){array1[i][j] = in.nextInt();}}// 给二维数组补充边界,防止下面操作时,数组越界for(int i=0; i<col+2; i++){array1[0][i] = Integer.MAX_VALUE;array1[row+1][i] = Integer.MAX_VALUE;}for(int i=0; i<row+2; i++){array1[i][0] = Integer.MAX_VALUE;array1[i][col+1] = Integer.MAX_VALUE;}int[][] map = new int[row+1][col+1];// 计算每个数的奔跑长度List<Integer> list = new ArrayList<Integer>();for(int i=1; i<=row; i++){for(int j=1; j<=col; j++){list.add(process(i, j, array1, map));}}// 得到最长的奔跑路径长度int Max=0;for(int i=0; i<list.size(); i++){if(Max < list.get(i))Max= list.get(i);}System.out.println(Max);}}// 递归出每个数的最长奔跑路径长度public static int process(int i, int j, int[][] array, int[][] map){int[] ret = new int[]{0,0,0,0};if(map[i][j] != 0) return map[i][j];// 如果map数组中已经有了当前这个数的最长奔跑长度,则不用计算了,直接返回if(array[i][j] > array[i+1][j] || array[i][j]>array[i][j+1] ||array[i][j] > array[i-1][j] || array[i][j] > array[i][j-1]){if(array[i+1][j] < array[i][j]){ret[0] =1 + process(i+1, j, array, map);}if(array[i-1][j] < array[i][j]){ret[1] =1 + process(i-1, j, array, map);}if(array[i][j+1] < array[i][j]){ret[2] =1 + process(i, j+1, array, map);}if(array[i][j-1] < array[i][j]){ret[3] =1 + process(i, j-1, array, map);}}else return 1;int temp; for(int x=0; x<1; x++){ // 不用全排序,只用得到最大值就可以for(int y=x+1; y<4; y++){if(ret[x] < ret[y]){temp = ret[x];ret[x] = ret[y];ret[y] = temp;}}}map[i][j] = ret[0];// 记录下当前位置已经算好的最长奔跑长度return ret[0];}}




阅读全文
0 0