劍指offer第二版 面試題14(java)

2021-09-13 03:58:07 字數 2451 閱讀 8965

面試題14:剪繩子

題目描述:

給定一根長度為n的繩子,請把繩子剪成m段(m、n都是整數,n>1並且m>1),每段繩子的長度記為k[0],k[1],…,k[m]。請問k[0]* k[1] * … *k[m]可能的最大乘積是多少? 

例如,當繩子的長度是8時,我們把它剪成長度分別為2、3、3的三段,此時得到的最大乘積是18。

邊界:m、n都是整數,n>1並且m>1

動態規劃方法:

1、定義函式表示為把長度為n的繩子剪成若干段後各段長度乘積的最大值。 

2、對於第一刀,我們有n-1種可能的選擇,可推導出f(n)=max; 

3、這是乙個從上至下的遞迴,但是這個遞迴存在很多重複的計算,所以使用自下而上的動態規劃,將子問題的最優解儲存。 

4、注意繩子剪成ix(n-i)和(n-i)xi是相同的;

5、注意不符合切割條件的輸入n,以及輸入為2、3長度時的結果,因為題中規定m>1。

貪婪演算法:

1、貪心演算法在對問題求解時,不從整體最優上加以考慮,所做出的是在某種意義上的區域性最優解; 

2、選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關; 

3、題目貪心策略:當n>=5時,盡可能多地剪長度為3的繩子;當剩下的繩子長度為4時,把繩子剪成兩段長度為2的繩子。

證明:當n≥5時,可以證明2(n-2)>n切3(n-2)>n且3(n-2)≥2(n-2)

之所以是剪成3,而不是更多:如果剪成4,則和剪成2一樣(2+2);如果剪成5,則又回到了1+4和2+3;如果剪成6,也回到了1+5和2+4,也是之前的問題,所以剪成3是更好的選擇。

方法一**中:

① 當n=0時,返回0;當n=1時,返回0(不符合條件);

n=2時,返回1(只能切成兩個1);n=3時,返回2,(只能切為乙個1和乙個2)

② 用動態規劃的方法,如長度為n,則可以切為 和【n-1】兩段,其中【n-1】段又可切為和【n-2】兩段……

從下到上進行運算,先算product[4]、product[4]、……、product[n]

③ product陣列中,product[i]代表,當i長度為繩子中被切分的一段時,能返回的最大長度

如product[0] 表示當繩子被切分為[0]和[n]時,為0的段能提供的最大乘積為0 (違反n>1)

product[1]表示當繩子被切分為[1]和[n-1]時,為1的段能提供的最大乘積為1

product[2]表示當繩子被切分為[2]和[n-2]時,為1的段能提供的最大乘積為2,即不切分該段

④ 初始化product數列時,長度為n+1,因為有長度為0的段值

eg:product[0] = 0

product[1] = 1

product[2] = 2

product[3] = 3

計算n=4時,能剪成的最大長度。可剪為1+3,2+2,分別為0和4,所以product[4]= 4

計算n=5時,可分為1+4,2+3,分別為4和6,所以product[5] = 6

不用考慮剪後的4又能怎麼剪,因為product[4]的值已經包含了長度為4的繩子可以返回的最大乘積

// 動態規劃

public class q14

public static int getmax(int n)

if(n==2)

if(n==3)

int product = new int[n+1];

product[0] = 0;

product[1] = 1;

product[2] = 2;

product[3] = 3;

int max = 0;

int temp = 0;

for(int i=4;i<=n;i++)

}product[i] = max;

system.out.printf("product[%d] id %d\n",i,max);

max = 0;

} return product[n];

}}

貪婪演算法只有方法不同,main函式相同,只貼了方法

public static int getmax(int n) 

if(n==2)

if(n==3)

int max = 1;

while(n>0) else if(n==4) else if(n>0 && n<3)

} return 0;

}

劍指offer第二版面試題14 剪繩子(java)

題目描述 給定一根長度為n的繩子,請把繩子剪成m段 m n都是整數,n 1並且m 1 每段繩子的長度記為k 0 k 1 k m 請問k 0 k 1 k m 可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到的最大乘積是18。分析 1 求乙個問題的最優解 ...

劍指offer第二版 面試題6(java)

面試題6 從尾到頭列印鍊錶 題目 輸入乙個鍊錶的頭結點,從尾到頭反過來列印出每個結點的值 鍊錶的結點定義如下 public class listnode 注意 面試中,如果打算修改輸入的資料,最好先問好是否資料是允許修改的 思路 1.遍歷順序從頭到尾,列印順序從尾到頭,第乙個結點最開始被訪問,但是最...

劍指offer第二版 面試題8 java

題目描述 給定乙個二叉樹和其中的乙個結點,請找出中序遍歷順序的下乙個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指標 分析 情況 一 有右子樹,這時只需要把其右孩子作為下乙個遍歷的 並不是要找的 節點,然後沿著該節點的左子樹 如果有的話 出發,直到遇到葉子節點,那麼該葉子節...