2017年完美世界秋招的原题。

原题链接:https://leetcode.com/problems/dungeon-game/description/


骑士救公主,每个格子可能加血也可能减血。而且到达每个格子时的血量必须大于等于1,问骑士初始最小血量是多少才能保证救到公主。骑士每次只能往右和往左走。好像可以压缩一下空间。。。。。。这里就不给出了.

我当时是从左上往后考虑的,一直没搞清楚。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class  Solution {
     public  int  calculateMinimumHP( int [][] dungeon) {
         if  (dungeon ==  null  || dungeon.length ==  0  || dungeon[ 0 ].length ==  0 return  0 ;
     
     int  m = dungeon.length;
     int  n = dungeon[ 0 ].length;
         ///走到m,n时所需要的最少血量
         int [][] health =  new  int [m][n];
         ///最后是整数的话,只需要一滴血就行,负数的话就是1+血
         health[m- 1 ][n- 1 ] = Math.max( 1 , 1 -dungeon[m- 1 ][n- 1 ]);
         //最后一列
         for ( int  i = m- 2 ; i>= 0  ;i--)
             health[i][n- 1 ] = Math.max( 1 ,health[i+ 1 ][n- 1 ] - dungeon[i][n- 1 ]);
         ///最后一行
         for ( int  j = n- 2 ; j>= 0 ;j--){
             health[m- 1 ][j] = Math.max( 1 ,health[m- 1 ][j+ 1 ] - dungeon[m- 1 ][j]);
         }
         ///中间的格子
         for ( int  i = m- 2 ; i>= 0 ;i--){
             for ( int  j = n- 2 ;j>= 0 ;j--){
                 int  right = Math.max( 1 ,health[i][j+ 1 ]-dungeon[i][j]);
                 int  down = Math.max( 1 ,health[i+ 1 ][j] - dungeon[i][j]);
                 health[i][j] = Math.min(down,right);
             }
         }
         return  health[ 0 ][ 0 ];
     }
}

可以参考这个过程

dungeon

-2,-3,3
-5,-10,1
10,30,-5

From the Dungeon grid, we can simply compute health for the [last row][last column].

Now we get

?,?,?
?,?,?
?,?,6

Now because the knight can only move rightward or downward in each step, we can compute all the health value for last row from right to left using its rightward neighbor. we can also compute all the health value for last column from bottom to up using its downward neighbor.

?,?,2
?,?,5
1,1,6

Now, we can compute all the health value using its downward neighbor and rightward neighbor(we use the min value of these 2 health value).

7,5,2
6,11,5
1,1,6