劍指 offer 貪心 動態規劃篇

2022-09-13 15:06:17 字數 3550 閱讀 3156

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的三段,此時得到...