剑指 offer 第 8 天
第 8 天
动态规划(简单)
剑指 Offer 10- I. 斐波那契数列
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:1
示例 2:
输入:n = 5
输出:5
提示:
0 <= n <= 100
题解思想:动态规划、矩阵快速幂、打表动态规划
动态规划:改写递归即可
class Solution {
int mod = (int)1e9+7;
public int fib(int n) {
if (n <= 1) return n;
int a = 0, b = 1;
for (int i = 2; i <= n; i++) {
int c = a + b;
c %= mod;
a = b;
b = c;
}
return b;
}
}
矩阵快速幂:记熟方法
class Solution {
static final int MOD = 1000000007;
public int fib(int n) {
if (n < 2) {
return n;
}
int[][] q = {{1, 1}, {1, 0}};
int[][] res = pow(q, n - 1);
return res[0][0];
}
public int[][] pow(int[][] a, int n) {
int[][] ret = {{1, 0}, {0, 1}};
while (n > 0) {
if ((n & 1) == 1) {
ret = multiply(ret, a);
}
n >>= 1;
a = multiply(a, a);
}
return ret;
}
public int[][] multiply(int[][] a, int[][] b) {
int[][] c = new int[2][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
c[i][j] = (int) (((long) a[i][0] * b[0][j] + (long) a[i][1] * b[1][j]) % MOD);
}
}
return c;
}
}
打表动态规划:
class Solution {
static int mod = (int) 1e9+7;
static int N = 110;
static int[] cache = new int[N];
public int fib(int n) {
if (n == 0) {
return 0;
}
if (n == 1 || n == 2) {
return 1;
}
if (cache[n] != 0) {
return cache[n];
}
cache[n] = (fib(n - 1) + fib(n - 2)) % mod;
return cache[n];
}
}
剑指 Offer 10- II. 青蛙跳台阶问题
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:2
示例 2:
输入:n = 7
输出:21
示例 3:
输入:n = 0
输出:1
提示:
0 <= n <= 100
题解思路:动态规划、矩阵快速幂
动态规划:与斐波拉契一样
class Solution {
public int numWays(int n) {
//递归方法 找通项公式
// 将大问题拆分成小问题 n级台阶有 numWays(n-1)+numWays(n-2)
//出口为 n=1 返回1 n=2 返回2
if(n==0||n==1) return 1;
if(n==2) return 2;
int s1=1,s2=2;
int sum;
//最优雅的方式 动态规划 且空间用的也少
for(int i=3;i<n+1;i++){
sum=(s1+s2)%1000000007;
s1=s2;
s2=sum;
}
return s2;
}
}
矩阵快速幂:
class Solution {
private final static int COS = 1000000007;
private int[][] res ={{1,0},{0,1}};
private int[][] temp ={{1,1},{1,0}};
public int numWays(int n) {
int num = fastPow(n);
return num;
}
public int fastPow(int n) {
while (n != 0) {
if((n&1) == 1) res = mul(res,temp);
temp = mul(temp,temp);
n = n>>>1;
}
return res[0][0];
}
public int[][] mul(int[][] a1, int[][] a2) {
int row = a1.length;
int col = a2[0].length;
int[][] c = new int[row][col];
for (int i=0; i<row; i++) {
for (int j=0; j<col; j++) {
long fac = 0l;
for (int k=0; k<a1[0].length;k++) {
long l1 = a1[i][k];
long l2 = a2[k][j];
fac += (l1*l2)%COS;
}
c[i][j] = (int)fac%COS;
}
}
return c;
}
}
剑指 Offer 63. 股票的最大利润
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
限制:
0 <= 数组长度 <= 10^5
题解思路:单调栈、动态规划
单调栈:每次记录当前最大值
class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) {
return 0;
}
Stack<Integer> stack = new Stack<Integer>();
stack.push(prices[0]);
int max = 0;
for (int i = 0; i < prices.length; i ++) {
if (stack.peek() > prices[i]) {
stack.pop();
stack.push(prices[i]);
} else {
max = Math.max(max, prices[i] - stack.peek());
}
}
return max;
}
}
动态规划:维护一个最低价格 cost,判断当前卖出获利是否大于之前卖出获利
class Solution {
public int maxProfit(int[] prices) {
if (prices.length < 2) return 0; // 没有卖出的可能性
// 定义状态,第i天卖出的最大收益
int[] dp = new int[prices.length];
dp[0] = 0; // 初始边界
int cost = prices[0]; // 成本
for (int i = 1; i < prices.length; i++) {
dp[i] = Math.max(dp[i - 1], prices[i] - cost);
// 选择较小的成本买入
cost = Math.min(cost, prices[i]);
}
return dp[prices.length - 1];
}
}
剑指 offer 第 8 天的更多相关文章
- 剑指Offer面试题:1.实现Singleton模式
说来惭愧,自己在毕业之前就该好好看看<剑指Offer>这本书的,但是各种原因就是没看,也因此错过了很多机会,后悔莫及.但是后悔是没用的,现在趁还有余力,把这本书好好看一遍,并通过C#通通实 ...
- 剑指Offer面试题:14.链表的倒数第k个节点
PS:这是一道出境率极高的题目,记得去年参加校园招聘时我看到了3次,但是每次写的都不完善. 一.题目:链表的倒数第k个节点 题目:输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的习惯,本题 ...
- 《剑指offer》面试题12:打印1到最大的n位数
面试题12:打印1到最大的n位数 剑指offer题目12,题目如下 输入数字n,按顺序打印出1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的三位数999 方法一 和面试题11< ...
- 《剑指offer》面试题11: 数值的整数次方
面试题11: 数值的整数次方 剑指offer面试题11,题目如下 实现函数double power(double base,int exponent),求base的exponent次方, 不得使用库 ...
- 剑指 Offer 题目汇总索引
剑指 Offer 总目录:(共50道大题) 1. 赋值运算符函数(或应说复制拷贝函数问题) 2. 实现 Singleton 模式 (C#) 3.二维数组中的查找 4.替换空格 ...
- 面试题目——《剑指Offer》
1.把一个字符串转换成整数——<剑指Offer>P29 2.求链表中的倒数第k个结点——<剑指Offer>P30 3.实现Singleton模式——<剑指Offer> ...
- 剑指offer习题集2
1.把数组排成最小的数 class Solution { public: static bool compare(const string& s1, const string& s2) ...
- 剑指offer习题集1
1.打印二叉树 程序很简单,但是其中犯了一个小错误,死活找不到,写代码要注意啊 这里左右子树,要注意是node->left,结果写成root->left vector<int> ...
- 剑指Offer:面试题20——顺时针打印矩阵(java实现)
题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数 字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1, ...
- 牛客网上的剑指offer题目
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 题目:请实现一个函数,将一 ...
随机推荐
- 第一课 Markdown 实操
1.Markdown (#加空格) 二级标题 (##加空格) 三级标题 (###加空格) 四级标题 (####加空格) 2.字体 Hello world 加粗(字体2边加**) Hello world ...
- HTML复习(19.背景样式)
重点 掌握背景颜色属性 掌握背景图片属性 背景样式简介 在CSS中,背景样式包括2个方面:①背景颜色:②背景图片.在Web1.0时代,都是使用background或者bgcolor这两个"H ...
- 苹果公司对蓝牙免提AT指令的扩充
介绍 苹果公司对蓝牙HF profile进行了一些HF AT指令的扩充.不过为了兼容起见,尽量实现HF标准规范规定的内容,如果标准规范没有规定相应的内容,为了适配苹果设备新增的功能,还是可以适应苹果公 ...
- 导出接口 生成doc文档
public function test1(){ echo ' <html xmlns:o="urn:schemas-microsoft-com:office:office" ...
- HDFS编程 —— 用Java API 操作HDFS
使用Java操作HDFS,首先需要创建maven工程,创建maven工程的方法:https://www.cnblogs.com/ynqwer/p/14540108.html. 在新建的maven工程的 ...
- 标记一下CF教育场的网址
(因为太难翻了,做到哪里标到哪,自用 Educational Codeforces Round 1 Educational Codeforces Round 2 Educational Codefor ...
- mybatis核心配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...
- Python爬虫之Scrapy制作爬虫
前几天我有用过Scrapy架构编写了一篇爬虫的代码案例深受各位朋友们喜欢,今天趁着热乎在上一篇有关Scrapy制作的爬虫代码,相信有些基础的程序员应该能看的懂,很简单,废话不多说一起来看看. 前期准备 ...
- 链表反转,C++实现
1 // To Compile and Run: g++ invert_list.cc -std=c++11 -Wall -O3 && ./a.out 2 3 4 #include & ...
- docker 配置 anaconda + jupyter notebook 纪要
首先,pull官方的镜像,名字叫:continuumio/anaconda3 首先的首先,如果默认还是需要sudo运行docker命令,可以考虑把当前用户加入到docker组(usermod -aG ...