剑指Offer---面试题9---斐波那契数列
时间:2019-12-14
本文章向大家介绍剑指Offer---面试题9---斐波那契数列,主要包括剑指Offer---面试题9---斐波那契数列使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
剑指Offer-面试题9---斐波那契数列
1、题目1:输出斐波那契数列
输入n,输出斐波那契数列位于第n位的值。
递归的方式效率会很低,因为会有大量重复的计算。所以这时按顺序推是个好办法。
我的解法:从前往后算,把计算过的值都存入数组中。
#include <iostream>
#include <vector>
using namespace std;
long long CalculateNums(vector<long long> nums,unsigned int n)
{
nums[0] = 0;
nums[1] = 1;
//每次计算时先检测之前是否已经计算过
if(n<nums.size()){
return nums[n];
}
//接着从未计算过的位置开始计算
for(int i=nums.size();i<=n;i++){
nums.push_back(nums[i-1] + nums[i-2]);
}
return nums[n];
}
int main()
{
int n;
vector<long long> nums;
//给初始的两个数预留空间
nums.resize(2);
while(cin>>n){
if(n<0){
cout<<"输入范围错误"<<endl;
}
else{
cout<<CalculateNums(nums,n)<<endl;
}
}
return 0;
}
2、题目2:青蛙跳台阶1
青蛙跳台阶1:青蛙一次可以挑1或2层台阶。求跳n层台阶有几种跳法。(n<=30)
跳台阶其实就和斐波那契数列基本一样。不再重复写了。
3、题目3:青蛙跳台阶2
青蛙跳台阶2:青蛙一次可以挑1、2、、n-1、n台阶。求跳n层台阶有几种跳法。(n<=30)
这道题的规律很好算:f(n) = 2^(n-1)
我的解法:我是用快速幂算的
long long CalculateWays(unsigned int n)
{
if(n==0)
return 0;
if(n==1)
return 1;
n--;
long long result = 1;
long long base = 2;
while(n != 0){
if(n%2 !=0){
result *= base;
}
base *= base;
n /= 2;
}
return result;
}
大佬的解法:位运算,一行代码搞定!
long long CalculateWays(int n)
{
if(n==0)
return 0;
return 1<<(n-1);
}
4、题目4:青蛙跳台阶3
青蛙跳台阶3:青蛙一次可以挑1或2层台阶。求跳n层台阶有几种跳法。(500>=n>=100)
这道题规定的范围明显超过了long long的范围,所以用到了大整数加运算。
我的解法:啰嗦的大整数+
#include <iostream>
#include <string>
using namespace std;
string CalculateWays(unsigned int n);
string BigNumAdd(string s1,string s2);
int main()
{
int n;
cin>>n;
if(n<=0){
cout<<"输入范围错误";
}
else{
cout<<CalculateWays(n);
}
return 0;
}
string CalculateWays(unsigned int n)
{
if(n==1)
return "1";
if(n==2)
return "2";
string lastlast = "1";
string last = "2";
string result = "0";
for(int i=3;i<=n;i++){
result = BigNumAdd(lastlast,last);
lastlast = last;
last = result;
}
return result;
}
string BigNumAdd(string s1,string s2)
{
int len1 = s1.size()-1;
int len2 = s2.size()-1;
string result = "";
int carry = 0;
//先算两个数都有的位
while(len1>=0 && len2>=0){
int add = s1[len1] - 48 + s2[len2] - 48 + carry;
carry = add/10;
add%=10;
char addChar = add+48;
result = addChar + result;
len1--;
len2--;
}
//再算位数多的
while(len1>=0){
int add = s1[len1] - 48 + carry;
carry = add/10;
add%=10;
char addChar = add+48;
result = addChar + result;
len1--;
}
while(len2>=0){
int add = s2[len2] - 48 + carry;
carry = add/10;
add%=10;
char addChar = add+48;
result = addChar + result;
len2--;
}
//最后是否进位
if(carry > 0){
char addChar = carry+48;
result = addChar + result;
}
return result;
}
大佬的解法:优质的大整数+
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string BigNumAddString(string s1,string s2)
{
string& longStr = s1.size()>=s2.size()?s1:s2;
string& shortStr = s1.size()<s2.size()?s1:s2;
//给短的字符串前面填充0
shortStr.insert(0,longStr.size()-shortStr.size(),'0');
string result;
//给result预留足够的空间
result.resize(s1.size()+s2.size()+1);
//取各自最后一个字符的下标(要从后向前加)
int longIndex = longStr.size()-1;
int shortIndex = shortStr.size()-1;
int resultIndex = result.size()-1;
//进位标志
int carry = 0;
//加运算
while(shortIndex>=0){
int add = longStr[longIndex--] - '0' + shortStr[shortIndex--] - '0' + carry;
carry = add/10;
result[resultIndex--] = add%10 + '0';
}
//最后是否进位
if(carry > 0){
result[resultIndex--] = carry + '0';
}
//截取从这个参数下标开始一直到结尾(把前面多余的0截掉)
result = result.substr(resultIndex+1);
return result;
}
string CalculateWays(unsigned int n)
{
//也可以使用一个数组,把每次计算结果存进去
if(n==1)
return "1";
if(n==2)
return "2";
string lastlast = "1";
string last = "2";
string result = "0";
for(int i=3;i<=n;i++){
result = BigNumAddString(lastlast,last);
lastlast = last;
last = result;
}
return result;
}
int main()
{
int n;
cin>>n;
if(n<=0){
cout<<"输入范围错误"<<endl;
}
else{
cout<<CalculateWays(n);
}
return 0;
}
5 新知识
string和一些容器可以使用resize预分配空间,这样可以直接使用对象+[]形式赋值。
原文地址:https://www.cnblogs.com/Fflyqaq/p/12039743.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法