Skip to content

Commit c57916e

Browse files
committed
剑指offer
1 parent f0fc3d1 commit c57916e

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed

Diff for: 剑指offer/变态跳台阶.md

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
### 题目描述
2+
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
3+
***可以跳一到n层台阶***
4+
### 思路
5+
```
6+
链接:https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387
7+
来源:牛客网
8+
9+
关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:
10+
11+
f(1) = 1
12+
13+
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
14+
15+
f(3) = f(3-1) + f(3-2) + f(3-3)
16+
17+
...
18+
19+
f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n)
20+
21+
22+
23+
说明:
24+
25+
1)这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。
26+
27+
2)n = 1时,只有1种跳法,f(1) = 1
28+
29+
3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
30+
31+
4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,
32+
33+
那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)
34+
35+
因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
36+
37+
5) n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论:
38+
39+
f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)
40+
41+
42+
43+
6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:
44+
45+
f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)
46+
47+
f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)
48+
49+
可以得出:
50+
51+
f(n) = 2*f(n-1)
52+
53+
54+
55+
7) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:
56+
57+
| 1 ,(n=0 )
58+
59+
f(n) = | 1 ,(n=1 )
60+
61+
| 2*f(n-1),(n>=2)
62+
```
63+
### 代码
64+
```c++
65+
class Solution {
66+
public:
67+
int jumpFloorII(int number) {
68+
if(number == 0 || number == 1)
69+
return number;
70+
else
71+
return 2*jumpFloorII(number - 1);
72+
}
73+
};
74+
```

Diff for: 剑指offer/构建乘积数组.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
### 题目描述
2+
给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。
3+
### 思路一
4+
暴力解法,直接双层循环
5+
```c++
6+
class Solution {
7+
public:
8+
vector<int> multiply(const vector<int>& A) {
9+
vector<int> ret(A.size(), 1);
10+
for(int i = 0; i<A.size(); i++)
11+
{
12+
for(int j = 0;j<ret.size(); j++)
13+
{
14+
if(i != j)
15+
ret.at(j) *= A.at(i);
16+
}
17+
}
18+
19+
return ret;
20+
}
21+
};
22+
```
23+
### 思路二
24+
![](https://uploadfiles.nowcoder.com/images/20160829/841505_1472459965615_8640A8F86FB2AB3117629E2456D8C652)
25+
B[i]的值可以看作下图的矩阵中每行的乘积。
26+
下三角用连乘可以很容求得,上三角,从下向上也是连乘。
27+
因此我们的思路就很清晰了,先算下三角中的连乘,即我们先算出B[i]中的一部分,然后倒过来按上三角中的分布规律,把另一部分也乘进去。
28+
```c++
29+
public class Solution {
30+
public int[] multiply(int[] A) {
31+
int length = A.length;
32+
int[] B = new int[length];
33+
if(length != 0 ){
34+
B[0] = 1;
35+
//计算下三角连乘
36+
for(int i = 1; i < length; i++){
37+
B[i] = B[i-1] * A[i-1];
38+
}
39+
int temp = 1;
40+
//计算上三角
41+
for(int j = length-2; j >= 0; j--){
42+
temp *= A[j+1];
43+
B[j] *= temp;
44+
}
45+
}
46+
return B;
47+
}
48+
}
49+
```

Diff for: 剑指offer/求1+2+3+...+n.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
### 题目描述
2+
求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
3+
### 思路
4+
利用短路 && 代替条件判断
5+
```c++
6+
class Solution {
7+
public:
8+
int Sum_Solution(int n) {
9+
int ans = n;
10+
ans && (ans += Sum_Solution(n-1));
11+
return ans;
12+
}
13+
};
14+
```

0 commit comments

Comments
 (0)