★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-zprzotpv-md.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess.git
The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately.github
Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers).微信
In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step.ide
Write a function to determine the knight's minimum initial health so that he is able to rescue the princess.函數
For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN
.佈局
-2 (K) | -3 | 3 |
-5 | -10 | 1 |
10 | 30 | -5 (P) |
Note:ui
一些惡魔抓住了公主(P)並將她關在了地下城的右下角。地下城是由 M x N 個房間組成的二維網格。咱們英勇的騎士(K)最初被安置在左上角的房間裏,他必須穿過地下城並經過對抗惡魔來拯救公主。spa
騎士的初始健康點數爲一個正整數。若是他的健康點數在某一時刻降至 0 或如下,他會當即死亡。code
有些房間由惡魔守衛,所以騎士在進入這些房間時會失去健康點數(若房間裏的值爲負整數,則表示騎士將損失健康點數);其餘房間要麼是空的(房間裏的值爲 0),要麼包含增長騎士健康點數的魔法球(若房間裏的值爲正整數,則表示騎士將增長健康點數)。
爲了儘快到達公主,騎士決定每次只向右或向下移動一步。
編寫一個函數來計算確保騎士可以拯救到公主所需的最低初始健康點數。
例如,考慮到以下佈局的地下城,若是騎士遵循最佳路徑 右 -> 右 -> 下 -> 下
,則騎士的初始健康點數至少爲 7。
-2 (K) | -3 | 3 |
-5 | -10 | 1 |
10 | 30 | -5 (P) |
說明:
騎士的健康點數沒有上限。
56ms
1 class Solution { 2 func calculateMinimumHP(_ dungeon: [[Int]]) -> Int { 3 var m:Int = dungeon.count 4 var n:Int = dungeon[0].count 5 var dp:[Int] = [Int](repeating:Int.max,count:n + 1) 6 dp[n - 1] = 1 7 for i in (0..<m).reversed() 8 { 9 for j in (0..<n).reversed() 10 { 11 dp[j] = max(1, min(dp[j], dp[j + 1]) - dungeon[i][j]) 12 } 13 } 14 return dp[0] 15 } 16 }
60ms
1 class Solution { 2 3 func calculateMinimumHP(_ dungeon: [[Int]]) -> Int { 4 let n = dungeon.count 5 if n > 0 { 6 let m = dungeon[0].count 7 var c = [[Int]](repeating:[Int](repeating: .max, count: m + 1), count: n + 1) 8 c[n][m-1] = 0 9 c[n-1][m] = 0 10 for i in stride(from: n-1, through: 0, by: -1) { 11 for j in stride(from: m-1, through: 0, by: -1) { 12 let next = min(c[i+1][j],c[i][j+1]) 13 var cur = -dungeon[i][j] + next 14 cur = max(cur, 0) 15 c[i][j] = cur 16 } 17 } 18 return c[0][0] + 1 19 } else { 20 return 1 21 } 22 } 23 }
60ms
1 class Solution { 2 func calculateMinimumHP(_ dungeon: [[Int]]) -> Int { 3 4 let m = dungeon.count 5 let n = dungeon[0].count 6 7 var dp = Array(repeating: Array(repeating: 0, count: n), count: m) 8 9 dp [m-1][n-1] = dungeon[m-1][n-1] < 0 ? -1 * dungeon[m-1][n-1] + 1 : 1 10 for i in stride(from: m-2, to: -1, by: -1) { 11 dp[i][n-1] = max(dp[i+1][n-1] - dungeon[i][n-1] , 1) 12 } 13 for j in stride(from: n-2, to: -1, by: -1) { 14 dp[m-1][j] = max(dp[m-1][j+1] - dungeon[m-1][j], 1) 15 } 16 17 for i in stride(from: m-2, to: -1, by: -1) { 18 for j in stride(from: n-2, to: -1, by: -1) { 19 let minIJ = min(dp[i][j+1], dp[i+1][j]) - dungeon[i][j] 20 dp[i][j] = max(minIJ, 1) 21 } 22 } 23 24 return dp[0][0] 25 } 26 }
68ms
1 class Solution { 2 func calculateMinimumHP(_ dungeon: [[Int]]) -> Int { 3 let rows = dungeon.count 4 let cols = dungeon[0].count 5 var dp = Array(repeating: Array(repeating: Int.max, count: cols + 1), count: rows + 1) 6 7 dp[rows][cols - 1] = 1 8 dp[rows - 1][cols] = 1 9 10 for i in stride(from: rows - 1, to: -1, by: -1 ) { 11 for j in stride(from: cols - 1, to: -1, by: -1 ) { 12 let mv = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j] 13 dp[i][j] = mv <= 0 ? 1 : mv 14 } 15 } 16 print(dp) 17 return dp[0][0] 18 } 19 }
80ms
1 class Solution { 2 var result: [[Int]]! 3 var flag: [[Bool]]! 4 func calculateMinimumHP(_ dungeon: [[Int]]) -> Int { 5 let row = dungeon.count 6 let column = dungeon.first!.count 7 result = Array(repeatElement(Array(repeatElement(0, count: column)), count: row)) 8 flag = Array(repeatElement(Array(repeatElement(false, count: column)), count: row)) 9 flag[row - 1][column - 1] = true 10 result[row - 1][column - 1] = dungeon[row - 1][column - 1] 11 12 let answer = calculateResult(dungeon) 13 return answer <= 0 ? 1 - answer : 1 14 } 15 16 func calculateResult(_ dungeon: [[Int]], _ n: Int = 0, _ m: Int = 0) -> Int { 17 if n == dungeon.count || m == dungeon.first!.count { 18 return -Int.max 19 } 20 if flag[n][m] == false { 21 flag[n][m] = true 22 result[n][m] = dungeon[n][m] + max(min(0, calculateResult(dungeon, n, m + 1)), 23 min(0, calculateResult(dungeon, n + 1, m))) 24 } 25 return result[n][m] 26 } 27 }