原题连接
1. 斐波那契数列
题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
思路
递归和循环的典型案例,就不多分析了,这里就说一点由于使用递归很简洁,但是也有其明显的缺点,递归是不断的的调用自身,函数调用是有时间和空间的消耗的,每一次函数调用都是要在内存栈中分配空间以保存参数、返回地址以及临时变量的,而且往栈里压入数据和弹出数据都是需要时间的,另外递归中很多的计算都是重复的,所以一般可以采用递归的思路来分析,写代码的时候可以用自下而上的循环来实现代码
代码
/**
* 斐波那契数列
* 递归写法
*/
private int Fibonacci(int n){
if (n<=0)
return 0;
if (n==1)
return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
//循环写法
private int Fibonacci2(int n){
if (n<=0)
return 0;
if (n ==1)
return 1;
int one = 1;
int two = 0;
int fibN = 0;
for (int i = 2; i <= n; i++) {
fibN = one +two;
two = one;
one = fibN;
}
return fibN;
}
2.跳台阶
这个题目之前的时候已经分析过了,这里就不分析了,不知道的可以看我前面的博客青蛙跳台阶
3.变态跳台阶
分析之前也分析过,这里直接贴代码
代码
//这里直接使用的循环来获得结果,也可以按照数学公式来计算
private int jumpFloor(int n){
if (n ==0)
return 0;
int[] result = new int[n+1];
result[0] = 1;
result[1] = 1;
for (int i = 2; i <= n; i++) {
result[i] = 0;
for (int j = 0; j < i; j++) {
result[i] +=result[j];
}
}
return result[n];
}
//数学公式
private int jumpFloor(int n){
return 1<<(n-1);
}
4.矩形覆盖
题目描述
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
思路
这个又是一个递归,斐波那契数列,代码就不写了,同上样的
5. 二进制中1的个数
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路
这题有很多解法,比如使用移位,在使用移位的时候,不能够直接对数字n进行移位,因为如果是负数的话,移位之后也要保证是负数,所以最高位会设为1,可能会进入死循环,不能正确统计到1的个数,可以使用unsigned int flag =1,让数字n与1进行位与运算,如果最右边是1,则结果为1,个数+1,然后将1进行左移,然后再去判断n的次低位是不是1.
这里介绍另外一种解法,就是将这个整数减1,然后再和原整数进行位与运算,这样会把整数最右边的1变为0,然后循环几次,就有几个1
比如说1100,减去1之后是1011,再与1100进行位与运算,结果是1000,这正好是把1100最右边的1变为0
代码
public int NumberOf1(int n) {
int count = 0;
while (n!=0){
++count;
n=(n-1)&n;
}
return count;
}
扩展
n& (n-1)这个运算,可以解决很多二进制问题,比如判断一个整数是不是2的整次方,也就是说明这整数的二进制表示中有且只有一位是1,只要与(n-1)进行位与运算判断是不是0就可以了
6.数值的整次方
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
思路
扫描二维码关注公众号,回复: 4939990 查看本文章
public double Power(double base, int exponent) {
boolean f = exponent >0;
if ((exponent = Math.abs(exponent)) == 0) {
return 1.0;
}
double result = Power(base, exponent >> 1);
result *= result;
if ((exponent % 2) != 0) {
result *= base;
}
return f ? result : 1.0 / result;
}