10-i. 斐波拉契數列
題意:面試題10- i. 斐波那契數列
思路:最基礎的動態規劃題。資料量比較大的時候不能使用遞迴,會報stackoverflow exception,最優的方式是迭代計算。
class solution
int a = 0;
int b = 1;
int index = 2;
int tmp;
while (index <= n)
return b;
}}
10-ii. 青蛙跳台階
題意:面試題10- ii. 青蛙跳台階問題
思路:同斐波拉契數列問題,最基礎的動態規劃問題。
class solution
int a = 1;
int b = 1;
int c = 0;
int i = 2;
while (i <= n)
return c;
}}
14-i. 剪繩子
題意:面試題14- i. 剪繩子
思路1:dp[i]表示長度為i的繩子,能夠得到的最大乘積數。dp[i+1]的計算方式為,每次可以剪掉1~i的長度j,其餘的繩子可以剪(即dp[i+1-j]),也可以不剪(即i+1-j),即
dp[i+1] = math.max(dp[i+1-j] * j, (i+1-j) * j), 其中j \(\in\) [1, i]
class solution
int dp = new int[n + 1];
dp[2] = 1;
for (int i = 3; i < n + 1; i ++)
}return dp[n];
}}
思路2:將繩子長度先盡可能的劃分為3的倍數,如果最後剩餘1,則拿出乙個已經分配的3來湊成4。
例如:5 = 3 + 2
6 = 3 + 3 -> 3 * 3 = 9
7 = 3 + 3 + 1 = 3 + 4 -> 3 * 4 = 12
……
class solution
int remind = n;
int multi = 1;
while (remind > 4)
return multi * remind;
}}
題意:試題14- ii. 剪繩子 ii
思路:同剪繩子i
class solution
int remind = n;
long multi = 1;
while (remind > 4)
return (int)((multi * remind) % 1000000007);
}}
題意:面試題19. 正規表示式匹配
思路:用dp[i][j]表示s字串前i個字串是否與p的前j個字串匹配,那麼所要求的結果就是dp[s.length()][p.length()]的值。
遞推式:對於某乙個位置dp[i][j],是否匹配可以分以下兩種情況:
(1)當s[i] == p[j]時,如果s[0...i-1]與p[0...j-1]匹配,那麼s[0...i]與p[0...j]匹配,反之不匹配。即dp[i][j] = dp[i-1][j-1];
(2)當s[i] != p[j]時。如果p[j] != 『*』,那麼s[0...i]與p[0...j]一定不匹配。如果p[j] == '*',代表p[j-1]位置的字元可以出現0次或多次
(a)當p[j-1]位置的字元不出現時,判斷s[0...i]與p[0...j-2]是否匹配即可,即dp[i][j] = dp[i][j-2]
(b)當p[j-1]位置的字元出現時,需要判斷s[i]位置上的字元是否與p[j-1] (注意可以是'.')相同,相同則dp[i][j] = dp[i-1][j]
class solution else if (parr[j - 1] == '*')
if (j > 1)}}
}return dp[slen][plen];
}}
42. 連續子陣列的最大和
題意:面試題42. 連續子陣列的最大和
思路:貪心。狀態轉移方程式為sum[i] = max(sum[i-1] + nums[i], nums[i]),其中sum[i]表示元素nums[0...i]的和。
class solution
return max;
}}
47. 禮物的最大價值
題意:面試題47. 禮物的最大價值
思路:動態規劃。遞推公式dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + grid[i][j],優化為一維後,第i行禮物最大價值:dp[j] = max(dp[j-1], dp[j]) + grid[i][j]。
class solution
for (int i = 1; i < grid.length; i ++) else }}
return dp[grid[0].length - 1];
}}
49. 醜數
題意:面試題49. 醜數
思路:動態規劃。醜數是2,3,5的倍數,下乙個醜數一定是前面某乙個數乘以2或3或5得到的最小數字。使用三個指標two、three、five分別指向2、3、5的倍數,下乙個更大的數將由這三個指標指向的數字分別乘2、乘3、乘5取最小值得到。取得最小值之後指標向前走一步。
class solution
if (dp[i] == dp[three] * 3)
if (dp[i] == dp[five] * 5)
}return dp[n - 1];
}}
60. n個骰子的點數
題意:面試題60. n個骰子的點數
思路:用freq[i][j]表示i個骰子,投出點數為j的次數。那麼遞推式為:
freq[i][j] = freq[i-1][j-1] + freq[i-1][j-2] + …… + freq[i-1][j-k](其中k<=6 且j-k>0,因為乙個骰子只能投出1~6點)
class solution
int k;
for (int i = 2; i <= n; i ++) }}
double sum = math.pow(6, n);
double res = new double[5 * n + 1];
for (int i = 0; i < res.length; i ++)
return res;
}}
63. **的最大利潤
題意:面試題63. **的最大利潤
思路:動態規劃。遍歷陣列的過程中,記錄陣列中最小的數字作為****的**。當前遍歷到的數字減去最小的數字就是最大的利潤。
class solution
return max;
}}
劍指offer 動態規劃
動態規劃 10 1.py 寫乙個函式,輸入 n 求斐波那契 fibonacci 數列的第 n 項。斐波那契數列的定義如下 class solution def fib self,n int int if n 0 return 0if n 1 return 1 dp 0 n 1 dp 0 0dp 1 ...
劍指Offer(八) 動態規劃
給你一根長度為n的繩子,請把繩子剪成整數長的m段 m n都是整數,n 1並且m 1,m n 每段繩子的長度記為k 1 k m 請問k 1 x.xk m 可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到的最大乘積是18。我們先定義函式f n 為把繩子剪成...
剪繩子(貪心 動態規劃)
準備找工作,開始刷題,牛客劍指offer 給你一根長度為n的繩子,請把繩子剪成整數長的m段 m n都是整數,n 1並且m 1 每段繩子的長度記為k 0 k 1 k m 請問k 0 xk 1 x.xk m 可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到...