題目:給定乙個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。每次只能向下或者向右移動一步。
示例:
輸入:[
[1,3,1],
[1,5,1],
[4,2,1]
]輸出: 7
解釋: 因為路徑 1→3→1→1→1 的總和最小。
思路:定義一維陣列dp用於記錄起始點到某一點最小距離,陣列長度為列長。除了dp[0]的值為0以外,其餘的都為最大值integer.max_value。
遍歷二維陣列:
1)在第一行(i = 0)中,起點到各個點的最短距離的方向就是一直往右走;
2)在第其他行(i > 0)中,由於只能往右或者下方向走,則起點到grid[i][0]的距離只能是一直往下;而對於其他列的點grid[i][j] (j > 0),則需要去比較上乙個節點dp[j - 1]與本節點dp[j]之間的大小,所謂的上個節點dp[j - 1]是指左邊的節點,而dp[j]]是指上邊的節點。
舉例說明:對於某一節點(2, 4),dp[3]是指起點到(2,3)的最小距離,而dp[4]是指起點到(1, 4)的最小距離。
public int minpathsum(int grid)
dp[0] = 0;
for(int i = 0; i < row; i++) else }}
return dp[col - 1];
}
題目:給定乙個整數 n,求以 1 ... n 為節點組成的二叉搜尋樹有多少種?
示例:
輸入: 3
輸出: 5
解釋:給定 n = 3, 一共有 5 種不同結構的二叉搜尋樹:
思路:假設n個節點構成的搜尋樹個數為dp(n),以n為根節點的搜尋樹個數為f(n)。則可知:
1)dp[n] = f(1) + f(2) + f(3) + ... + f(n)
2)當i為根節點時,左子樹節點為[1, i - 1],總共i - 1個節點;右子樹節點為[i + 1, n],總共n - i個節點。因此f(i) = dp(i - 1) * dp(n - i)。
由上面兩個式子可得:dp(n) = dp(0) * dp(n - 1) + dp(1) * dp(n - 2) + ... + dp(n - 1) * dp(0)。
舉例說明:當n=3時,dp(3) = dp(0) * dp(2) + dp(1) * dp(1) + dp(2) * dp(1)。即式子為dp(i) = dp(j) * (i - j - 1) 【j屬於[0, i)】
public int numtrees(int n)
}return dp[n];
}
題目:給你乙個整數陣列 nums ,請你找出陣列中乘積最大的連續子陣列(該子陣列中至少包含乙個數字)。
示例1:
輸入: [2,3,-2,4]
輸出: 6
解釋: 子陣列 [2,3] 有最大乘積 6。
示例2:
輸入: [-2,0,-1]
輸出: 0
解釋: 結果不能為 2, 因為 [-2,-1] 不是子陣列。
思路:
遍歷陣列,每個位置的最大連續子陣列的最大乘積有三種選擇:
(1)選擇自己本身nums[i];
(2)選擇本身與之前記錄的最大值相乘:curmax * nums[i];
(3)選擇本身與之前記錄的最小值相乘:curmin * nums[i],因為nums[i]可能為負數,與同樣可能為負數的curmin 相乘可能得到更大值。
public int maxproduct(int nums)
return res;
}
乙個小偷計畫偷竊沿街的房屋。每間房內都藏有一定的現金,但相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。
示例 1:
輸入: [1,2,3,1]
輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) ,然後偷竊 3 號房屋 (金額 = 3)。偷竊到的最高金額 = 1 + 3 = 4 。
思路:定義乙個陣列dp表示前i個房子中能搶到的最大現金:、
public int rob(int nums)
return dp[length - 1];
}
題目:在乙個由 0 和 1 組成的二維矩陣內,找到只包含 1 的最大正方形,並返回其面積。
示例:
輸入:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
輸出:4
思路:假設定義乙個陣列dp[row][col],它表示以(i, j)為右下角所構成的最大正方形邊長。
(1)初始時,即i = 0或j = 0時,dp[i][j] = matrix[i][j] - '0'。在第一行或第一列的元素為右下角時,它們構成的正方形就是他們本身。
(2)對於其他行和列(i,j),若dp[i][j] = 1,則它們的值dp[i][j]依賴於它的上方(i,j - 1),它的左方(i - 1,j),它的左上方(i - 1,j - 1),若這三個值剛好相等,假設為x,那麼dp[i][j] = x + 1;若三個值不相等,那麼如果把三個正方形合起來,就會缺少某個角落,因此只能選三個中最小的那個,再加上1。
(3)最終得到的最大值maxcnt * maxcnt就是正方形面積。
上面我們定義的是二維陣列,同樣我們可以改為一維陣列dp[col]。每次遍歷時,我們用乙個變數topleft來記錄dp[j],這樣在當matrix[i][j]為1時,topleft表示的就是左上方或者左邊的值。
public int maximalsquare(char matrix) else
maxcnt = math.max(dp[j], maxcnt);}}
return maxcnt * maxcnt;
}
題目:給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。
示例 1:
輸入: coins = [1, 2, 5], amount = 11
輸出: 3
解釋: 11 = 5 + 5 + 1
示例 2:
輸入: coins = [2], amount = 3
輸出: -1
思路:定義陣列dp[amount + 1],dp[i]表示湊成金額i 所需的最少硬幣個數。遍歷所持有的硬幣值num,可以得出:
dp[i] = min(dp[i], dp[i - num] + 1
public int coinchange(int coins, int amount) }}
return dp[amount] == amount + 1 ? -1 : dp[amount];
}
leetcode 動態規劃
題目如下 給定乙個整型陣列,至少有乙個元素,請計算子陣列最大乘積是多少?子陣列必須是原陣列中連續的一串數字構成的陣列。整數可正可負。例如 給定陣列 2,3,2,4 經過計算,得到最大乘積為6。子陣列為 2,3 根據原貼的解題思路,這道題可以用動態規劃來解,但難度在 呢?負負得正,就可惡在這裡。那這個...
Leetcode 動態規劃
題目 原題鏈結在這裡 最長字串鏈。給乙個單詞列表,找乙個詞鏈,使得詞鏈後乙個單詞由前乙個單詞增加乙個字元得到,求最長詞鏈長度。解答 1 根據詞鏈的定義,短的單詞可以由長的單詞減去單詞中乙個字元得到。因此可以先對單詞列表,按照單詞的長度從大到小排序。2 單詞的最大長度為 16,因此可以對於每個單詞 w...
leetcode 動態規劃
3 動態規劃三要素 重疊子問題 最優子結構 狀態轉移方程 4 狀態轉移方程最難的 明確 狀態 定義 dp 陣列 函式的含義 明確 選擇 明確 base case f 0 0,f 1 1 f n f n 1 f n 2 其中 n 1.1 遞迴計算 複雜度高,指數級別 超時 時間複雜度 o 2 n cl...