上一篇:https://blog.csdn.net/qq_41345173/article/details/104235084
1. 跳臺階
一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法(先後次序不同算不同的結果)。
int jumpFloor(int number) {
int pre=0, next=1, now=0;
while(number--){
now=pre+next;
pre=next;
next=now;
}
return now;
}
2. 變態跳臺階
一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
int jumpFloorII(int number) {
int res=1;
while(number>1){
res *=2;
number--;
}
return res;
}
注意:此時有數學歸納法可知f(n)=2^(n-1)種跳法
3. 矩形覆蓋
我們可以用2*1的小矩形橫着或者豎着去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?
int rectCover(int number) {
int pre = 0, next = 1, now = 0;
while(number--){
now = pre+next;
pre = next;
next = now;
}
return now;
}
和第一題跳臺階一個道理,當n=1時右一種方法,n=2時有兩種方法,當n=n時,若選擇豎着放相當於f(n-1)的方法,若橫着放相當於f(n-2)的放法。故這是一個不完全符合斐波那契數列的數列
4. 矩陣中的路徑
題目鏈接: https://www.nowcoder.com/practice/
class Solution {
public:
bool hasPathCore(char* matrix, int rows, int cols,int row,int col,char* str,int &pathLength,bool *visited){
if(str[pathLength]=='\0')
return true;
bool hasPath = false;
if(row>=0&&row<rows&&col>=0&&col<cols&&matrix[row*cols+col]==str[pathLength]&&!visited[row*cols+col]){
++pathLength;
visited[row*cols+col] = true;
hasPath = hasPathCore(matrix,rows,cols,row,col-1,str,pathLength,visited)||
hasPathCore(matrix,rows,cols,row,col+1,str,pathLength,visited)||
hasPathCore(matrix,rows,cols,row-1,col,str,pathLength,visited)||
hasPathCore(matrix,rows,cols,row+1,col,str,pathLength,visited);
if(!hasPath){
--pathLength;
visited[row*cols+col] = false;
}
}
return hasPath;
}
bool hasPath(char* matrix, int rows, int cols, char* str)
{
if(matrix==nullptr||rows<1||cols<1||str==nullptr)
return false;
int len = rows*cols, i;
bool *visited = new bool[len];
memset(visited,0,len);
int pathLength = 0;
for(int row=0;row<rows;++row){
for(int col=0;col<cols;++col){
if(hasPathCore(matrix,rows,cols,row,col,str,pathLength,visited)){
return true;
}
}
}
delete []visited;
return false;
}
};
回溯法的典型應用,顯然遞歸要比迭代編碼方便的多。
5. 機器人的運動範圍
地上有一個m行和n列的方格。一個機器人從座標0,0的格子開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數位之和大於k的格子。 例如,當k爲18時,機器人能夠進入方格(35,37),因爲3+5+3+7 = 18。但是,它不能進入方格(35,38),因爲3+5+3+8 = 19。請問該機器人能夠達到多少個格子?
class Solution {
public:
int getDigitSum(int number){
int sum=0;
while(number>0){
sum +=number%10;
number /=10;
}
return sum;
}
bool check(int threshold, int rows, int cols, int row, int col, bool *visited){
if(row>=0&&row<rows&&col>=0&&col<cols&&getDigitSum(row)+getDigitSum(col)<=threshold&&!visited[row*cols+col])
return true;
return false;
}
int movingCountCore(int threshold, int rows, int cols, int row, int col, bool *visited){
int count=0;
if(check(threshold,rows,cols,row,col,visited)){
visited[row*cols+col] = true;
count =1+ movingCountCore(threshold,rows,cols,row-1,col,visited)+
movingCountCore(threshold,rows,cols,row+1,col,visited)+
movingCountCore(threshold,rows,cols,row,col-1,visited)+
movingCountCore(threshold,rows,cols,row,col+1,visited);
}
return count;
}
int movingCount(int threshold, int rows, int cols)
{
if(threshold<0||rows<=0||cols<=0)
return 0;
int len = rows*cols;
bool *visited = new bool[len];
memset(visited,0,len);
int count = movingCountCore(threshold,rows,cols,0,0,visited);
delete []visited;
return count;
}
};
和上一題一樣也是回溯法的典型應用,重點是破題,出發點爲起始點,然後 對每一個周邊點做判斷是否可行,若可行繼續判斷周邊值的周邊值之和,經過層層遞歸可得最終結果。
6.剪繩子
給你一根長度爲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的三段,此時得到的最大乘積是18。
class Solution {
public:
int cutRope(int number) {
if(number<2)
return 0;
if(number==2)
return 1;
if(number==3)
return 2;
int product[number];
product[0]=0,product[1]=1,product[2]=2,product[3]=3;
int max;
for(int i=4;i<=number;++i){
max = 0;
for(int j=1;j<=i/2;++j){
int mid = product[j]*product[i-j];
if(mid>max)
max = mid;
}
product[i] = max;
}
return max;
}
};
動態規劃的巧妙應用,還有一種貪心算法,高明的設計思路,需要推導