第六七八题

这篇博客介绍了如何使用两个栈来模拟队列的操作,包括在队列尾部插入元素(appendTail)和在队首删除元素(deleteHead)。此外,还探讨了一只青蛙跳台阶的问题,通过递归和动态规划两种方法解决,计算出跳上n级台阶的不同跳法,并解释了在大数计算中取模1e9+7的原因。
摘要由CSDN通过智能技术生成

package exercise06;


import java.util.Stack;

//用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,
// 分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
public class CQueue {
    //思路:入队时直接入栈,出队时,将栈1内容出栈入栈到栈2,然后再出栈
    Stack stack1,stack2;
    public CQueue() {
        stack1 = new Stack<Integer>();
        stack2 = new Stack<Integer>();
    }

    public void appendTail(int value) {
        stack1.push(value);
    }

    public int deleteHead() {
        if (stack2.isEmpty()){
            if (stack1.isEmpty()){
                return -1;
            }
            while (!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return (int) stack2.pop();
    }
}

第七题和第八题一样,下面代码是第八题

package exercise08;


//一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
//答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
public class Solution {
    //思路:类似迷宫,这里每次两种选择,走完回溯
    static int kinds = 0;
    public static int numWays(int n) {
        if (n == 0){
            kinds++;
            return 1;
        }else if (n < 0){
            return -1;
        }
        int select = 0;
        while (select < 2){
            if (select == 0){
                numWays(n-1);
            }
            if (select == 1){
                numWays(n-2);
            }
            select++;
        }
        return (int) (kinds % (1e9+7));
    }

    public static void main(String[] args) {
        int ways = numWays(41);
        System.out.println(ways);
    }
    /*
    PS : 为什么要模1000000007(跟我念,一,八个零,七)。参考https://www.liuchuo.net/archives/645

    大数相乘,大数的排列组合等为什么要取模
1000000007是一个质数(素数),对质数取余能最大程度避免结果冲突/重复
    int32位的最大值为2147483647,所以对于int32位来说1000000007足够大。
    int64位的最大值为2^63-1,用最大值模1000000007的结果求平方,不会在int64中溢出。
    所以在大数相乘问题中,因为(a∗b)%c=((a%c)∗(b%c))%c,所以相乘时两边都对1000000007取模,再保存在int64里面不会溢出。
    这道题为什么要取模,取模前后的值不就变了吗?
    确实:取模前 f(43) = 701408733, f(44) = 1134903170, f(45) = 1836311903, 但是 f(46) > 2147483647结果就溢出了。

    _____,取模后 f(43) = 701408733, f(44) = 134903163 , f(45) = 836311896, f(46) = 971215059没有溢出。

    取模之后能够计算更多的情况,如 f(46)

    这道题的测试答案与取模后的结果一致。

    总结一下,这道题要模1000000007的根本原因是标准答案模了1000000007。不过大数情况下为了防止溢出,模1000000007是通用做法,原因见第一点。

    -------leetcode某位网友ajslpzcd所写,这里自学借用
     */
}

package exercise08;

public class Solution1 {
    //动态规划方法
    //n个台阶是在n-1台阶基础上加1步,n-2台阶基础上加2步,所以n台阶种类应该等于n-1加上n-2种类数
    public int numWays(int n) {
        int a = 1,b = 1,num;
        for (int i = 0;i < n;i++){
            num = (a + b) % 1000000007;
            a = b;
            b = num;
        }
        return a;
    }

    public static void main(String[] args) {
        Solution1 solution1 = new Solution1();
        System.out.println(solution1.numWays(41));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新手学java2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值