刷题week1 递归递推 recursion

recursion
把问题分拆成一个一个更小的问题,最后汇总

一个简单的例子

//f(n) = f(n-1) + n;
public static int function(int n){
	//base case 初始值
	if (n == 0) {
		return 0;
	}
	//function函数
	return function(n-1) + n;
	//所有数据存储在stack(栈)中
	//一直到n==0,最后return 0, 才会往后慢慢加数据
	//最后return function(n).
}
	

三个要素:

  1. 明确函数的功能,并且consistent
  2. 找出初始结束条件(n=0, n=1, n=2)
  3. 函数等价关系, f(n)和 f(n-1)…的关系

再来一个例子,这个例子的等价关系需要有前提条件
在这里插入图片描述
类似的例子还有factorial, power,都可以运用递归来构造 函数

然后 递推(从下往上)和递归(从上往下,先全轮一遍才返回,先递再归)的区别 是方向相反

但是递归有时候会造成空间与时间的极度浪费

  1. 超时
  2. 内存不够,Stack Overflow, 大量重复计算

所以需要优化

例题1:
剑指offer16

出错,这里需要注意int的范围

int型的范围, 取值范围是【-2147483648 至2147483647) [-2^31, 2^31-1]
所以当取到2147483647的时候,报错

一种解法可以用long型替代int型,防止溢出。
再是指数分奇偶讨论,有效让n变小,降低时间复杂度 [ O(n)减少到O(log(n)) ] (int->long)

if(n % 2 == 1){
	return x * myPow(x, n - 1);
}else{
//偶数情况, x^8 = (x^2)^4
	return myPow(x * x, n / 2);

作者:edelweisskoko
链接:https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/solution/jian-zhi-offer-16-shu-zhi-de-zheng-shu-c-rgqy/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
    //public static void main(String[] args){
    //    myPow(2,3);
    //}
    public double myPow(double x, int n){
        //一个特例,throw exception
        if (x==0.0) {
            throw new IllegalArgumentException();
        }
        //把n的值储存在long型变量里
        long num = (long) n;
        return calc(x,num);
    }

    public double calc(double x, long n) {
        //base case, if n=0, myPow is 1, if n=1, myPow is x, if n=-1, myPow is 1/x.
        //if n < 0, myPow is 1/x^n
        //function: f(n) = f(n-1) ^ x
        if (n == 0) {
            return 1.0;
        }
        if(n == 1){
            return x;
        }
        if (n < 0) {
            // 1/x^|n|
            return 1.0/calc(x,Math.abs(n));
        }else if (n % 2 == 0) {
            return calc(x * x , n / 2) ;
        }else {
            return calc(x * x , n / 2) * x ;
        }
        
    }
}

原题LeetCode地址
当然,本题还有多种解法,迭代法,快速幂解法,就不在这里一一赘述了。

(n&1) (判断奇偶)n为偶,值为0,n为奇,值为1.
n>>=1 相当于 n = n>>1, shifts all bits to the right (等于除以2)

例题2:
LeetCode 62

//import java.util.Arrays;
class Solution {
    public int uniquePaths(int m, int n) {
        //dp - dynamic programming 动态规划

        //[m-1][n]的路线和到[m][n-1]的路线和汇总
        //if(m==1||n==1)return 1;
        //return uniquePaths(m, n-1)+uniquePaths(m-1,n);
        //建一个数组储存数据
        int[][] route = new int[m][n] ;
        //Array completely filled with 0
        // Fill each row with 0. 
        //for (int[] row : route){
        //    Arrays.fill(row, 0);
        //}
        
        //嵌套for循环
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                //base case是当i=0或j=0,对应[i][1]或者[1][j],此时只有一种方法,所以route[i][j]=1
                if(i==0 || j==0){
                    route[i][j]=1;
                }else{
                    //方程式关系
                    route[i][j]= route[i-1][j] + route[i][j-1];
                }
            }
        }
        //数组从route[0][0]开始,所以最后[m][n] 是 route[m-1][n-1]。
        return route[m-1][n-1];
    }
    
}

例题3:
在这里插入图片描述

例题4:
数楼梯 洛谷p1225
50%在这里插入图片描述
100%

java高精度算法
import java.math.BigInteger;
Scanner sc=new Scanner(System.in);

   大数操作
   BigInteger a=sc.nextBigInteger();
   BigInteger b=sc.nextBigInteger();
   BigInteger d = new BigInteger("1");
   BigInteger e = BigInteger.ONE;
   BigInteger c=a.add(b);
   BigInteger c=a.multiply(b);
   BigInteger c=a.divide(b);
   BigInteger c=a.subtract(b);
   BigInteger c=a.max(b);
   BigInteger c=a.divideAndRemainder(b);
import java.util.*;
import java.math.*;
//java自带高精尖,import java.math.BigInteger
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        //两个大数
        // 1 ->1
        // 2 ->1
        BigInteger b1 = new BigInteger("1");
		BigInteger b2 = new BigInteger("1");
		//负数和0, return 0
		if(N<1) {
		    System.out.println(0);
		}else if(N<3){
		    //1,2 return 1,2
		    System.out.println(1);
		}else{
		    //f(n)=f(n-1)+f(n-2)
		    for(int i = 1; i < N; i++) {
				BigInteger temp = b2;
				b2 = b1.add(b2);
				b1 = temp;
			}
			System.out.println(b2);
		}
		//close scanner
		in.close();
    }  
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值