1、斐波那契数列
题目描述
求斐波那契数列的第 n 项,n <= 39。
解题思路:
1)n=0,n=1的时候,f(n)等于本身,否则就等于前两项之和
2)解决方法:1、采用数组,计算保存所有序列的数,初始化f(1)=1; i=2循环到i=n; f(i) = f(i-1) +f(i-2) ; 这样时间复杂度为: O(n)
2、只保存前两项数据,进行计算。int fbi=0, pre1 = 0, pre2=1; i=2循环到i=n; fbi = pre1+pre2; pre1 = pre2; pre2 = fbi; 这样时间复杂度为: O(1). 减少了开销。
剑指offer的代码:
- public class Solution {
- public int Fibonacci(int n) {
- if(n<=1) return n;
- int array[] = new int [n+1];
- array[0]=0;
- array[1]=1;
- int result=0;
- for(int i=2;i<=n;i++){
- array[i] = array[i-1]+array[i-2];
- }
- return array[n];
- }
- }
本机测试代码:
- public class testFibonacci101 {
- /**
- * @param ycy
- */
- public static int searchFibonacci1(int n){ //原始得斐波那契数,采用数组存储所有的斐波那契数,直到n,返回需要的数。复杂度降低到O(n)
- if(n <= 1){
- return n;
- }
- int fibonacci[] = new int[n+1];
- fibonacci[0] = 0;
- fibonacci[1] = 1;
- for(int i=2;i<=n;i++){
- fibonacci[i] = fibonacci[i-1] + fibonacci[i-2];
- }
- return fibonacci[n];
- }
- public static int searchFibonacci2(int n){ //第i项,只与第i-1项和i-2项有关系,所以只保存前两项,进行求解,这样复杂度降低到O(1)
- if(n <= 1){
- return n;
- }
- int fibonacci = 0,fibpre1 = 0,fibpre2 = 1;
- for(int i=2;i<=n;i++){
- fibonacci = fibpre1 + fibpre2;
- fibpre1 = fibpre2;
- fibpre2 = fibonacci;
- }
- return fibonacci;
- }
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- System.out.println(searchFibonacci1(45));
- System.out.println(searchFibonacci2(45));
- }
- }
2、矩阵覆盖
题目描述
我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2*1 的小矩形无重叠地覆盖一个 2*n 的大矩形,总共有多少种方法?
解题思路
当 n 为 1 时,只有一种覆盖方法;
当 n 为 2 时,有两种覆盖方法;
要覆盖 2*n 的大矩形,可以先覆盖 2*1 的矩形,再覆盖 2*(n-1) 的矩形;或者先覆盖 2*2 的矩形,再覆盖 2*(n-2) 的矩形。而覆盖 2*(n-1) 和 2*(n-2) 的矩形可以看成子问题。该问题的递推公式如下:
剑指offer在线测试:
- public class Solution {
- public int RectCover(int target) {
- //f(0)=0;f(1)=1;f(2)=2;f(3)=3;f(4)=5
- if(target<=3) return target;
- int array[]= new int[target+1];
- array[0]=0;array[1]=1;array[2]=2;array[3]=3;
- for(int i=4;i<=target;i++)
- array[i] = array[i-1] + array[i-2];
- return array[target];
- }
- }
本机测试:
- public class testMatrixCover102 {
- /**
- * @param ycy
- * 题目描述:我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2*1 的小矩形无重叠地覆盖一个 2*n 的大矩形,总共有多少种方法?
- * 解决思路:1)经过推理可以发现,f(1)=1, f(2)=2, f(3)=3, f(4)=5 所以 f(1)=1 f(2)=2 f(n)=f(n-1)+f(n-2)
- *和斐波那契数一种解决思路
- */
- public static int matrixCover(int n){
- if(n<=2){
- return n;
- }
- int fn = 0, pre1 = 1, pre2 = 2;
- for(int i=3;i<=n;i++){
- fn = pre1 + pre2;
- pre1 = pre2;
- pre2 = fn;
- }
- return fn;
- }
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- System.out.print(matrixCover(4));
- }
- }
3、跳台阶
题目描述
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
解题思路
当 n = 1 时,只有一种跳法;
当 n = 2 时,有两种跳法;
跳 n 阶台阶,可以先跳 1 阶台阶,再跳 n-1 阶台阶;或者先跳 2 阶台阶,再跳 n-2 阶台阶。而 n-1 和 n-2 阶台阶的跳法可以看成子问题,该问题的递推公式为:
剑指offer代码:
- public class Solution {
- public int JumpFloor(int target) {
- if(target<=2) return target;
- int array[] = new int[target+1];
- array[0]=0;
- array[1]=1;
- array[2]=2;
- for(int i=3;i<=target;i++){
- array[i] = array[i-1] + array[i-2];
- }
- return array[target];
- }
- }
本地测试代码如下:
- public class jumpStep103 {
- /**
- * @param ycy
- * 题目描述:一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
- * 解决思路:f(1)=1, f(2)=2,f(3)=3,f(4)=5 f(i)=f(i-1) + f(i-2)
- */
- public static int jumpStep(int n){
- if(n<=2){
- return n;
- }
- int js = 0, jspre1 = 1, jspre2 = 2;
- for(int i=3;i<=n;i++){
- js = jspre1 + jspre2;
- jspre1 = jspre2;
- jspre2 = js;
- }
- return js;
- }
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- System.out.print(jumpStep(5));
- }
- }
4、变态跳台阶
题目描述
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级... 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
解题思路
1) f(n-1) = f(n-2) + f(n-3) + ... + f(0) f(n) = f(n-1) + f(n-2) + ... + f(0)所以
采取嵌套循环,每次i=1循环到i<n,嵌套j=0到j<i,一直进行dp[i] += dp[j]
2) f(n-1) = f(n-2) + f(n-3) + ... + f(0)与f(n) = f(n-1) + f(n-2) + ... + f(0)进行推导
f(n) - f(n-1) = f(n-1) 所以f(n) = 2*f(n-1); 所以dp = 1,dppre = 1; i=2循环到i<=n; dp = 2*dppre; dppre = dp;
剑指offer代码:
- public class Solution {
- public int JumpFloorII(int target) {
- //f(0)=0,f(1)=1,f(2)=2;f(3)=4;f(4)=8 f(n)= 2*f(n-1)
- int array[] = new int[target+1];
- if(target<=2) return target;
- array[0]=0; array[1]=1; array[2]=2;
- for(int i=3;i<=target;i++)
- array[i] = 2*array[i-1];
- return array[target];
- }
- }
本地代码:
- import java.util.Arrays;
- public class strageJumpStep104 {
- /**
- * @param ycy
- * 题目描述:一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级... 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
- * 解题思路:
- * 1)f(n-1) = f(n-2) + f(n-3) + ... + f(0) f(n) = f(n-1) + f(n-2) + ... + f(0)所以
- * 采取嵌套循环,每次i=1循环到i<n,嵌套j=0到j<i,一直进行dp[i] += dp[j]
- * 2)f(n-1) = f(n-2) + f(n-3) + ... + f(0)与f(n) = f(n-1) + f(n-2) + ... + f(0)进行推导
- * f(n) - f(n-1) = f(n-1) 所以f(n) = 2*f(n-1); 所以dp = 1,dppre = 1; i=2循环到i<=n; dp = 2*dppre; dppre = dp;
- */
- public static int strageJumpStep1(int n){ //f(n-1) = f(n-2) + f(n-3) + ... + f(0)
- int dp[] = new int[n]; //f(n) = f(n-1) + f(n-2) + ... + f(0)
- Arrays.fill(dp, 1);
- for(int i=1;i<n;i++){
- for(int j=0;j<i;j++){
- dp[i] += dp[j];
- }
- }
- return dp[n-1];
- }
- public static int strageJumpStep2(int n){ //
- int dp = 1,dppre = 1;
- for(int i=2;i<=n;i++){
- dp = 2*dppre;
- dppre = dp;
- }
- return dp;
- }
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- System.out.println(strageJumpStep1(8));
- System.out.println(strageJumpStep2(8));
- }
- }
扫码关注一起随时随地学习!!!就在洋葱攻城狮,更多精彩,等你来!!