1.斐波那契数列
【题目】
【思路】
- 暴力递归法:看代码
- 动态规划法:看代码
- 矩阵求幂法:看代码
【代码】
暴力递归法
class Solution {
public int fib(int n) {
if(n<=1)
return n;
return f(n-1)+f(n-2);
}
}
动态规划法
class Solution {
public int fib(int n) {
if(n<=1)
return n;
return f(n);
}
int f(int n){
int a=0;
int b=1;
int c=0;
for(int i=2;i<=n;i++){
c=(a+b)%1000000007;
a=b;
b=c;
}
return c;
}
}
矩阵求幂法
我不会
2.青蛙跳台阶问题
【题目】
【思路】
动态规划的入门级别的题
与上一道题类似,看代码
【代码】
class Solution {
public int numWays(int n) {
if(n<=1)
return 1;
int a=1;
int b=1;
int c=0;
for(int i=2;i<=n;i++){
c=(a+b)%1000000007;
a=b;
b=c;
}
return c;
}
}
3.旋转数组的最小数字
【题目】
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
【思路】
用类似于二分查找的方法,对数组一直进行削减,直至剩下的是最小元素。其中的细节在下方代码中都有注释
【代码】
class Solution {
public int minArray(int[] numbers) {
//将两个指针定位到数组的两端
int l=0;
int r=numbers.length-1;
//只要不是相等,或者越界就一直执行(越界基本不可能)
while(l<r){
//如果最左小于最右,那么这个旋转数组并没有旋转,直接返回
if(numbers[r]>numbers[l]){
return numbers[l];
}
int mid=(r+l)/2;
//如果中间大于最左,那么左半边是顺序的,不存在有最小的可能
if(numbers[l]<numbers[mid]){
l=mid+1;
//如果中间小于最右,那么右半边是顺序的,不存在有最小的可能(不排除中间是最小的可能)
}else if(numbers[r]>numbers[mid]){
r=mid;
//剩下的情况就是存在相等的元素,跳过就行
}else{
l++;
}
}
return numbers[l];
}
}