概述
继续刷题。。。
第九题
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
解题思路
这道题的名字叫做变态跳台阶问题,那为什么叫变态我就不知道了,其实和第8题思路差不多。
- 假设第一次青蛙跳1级,那剩余n-1级,也就是还有f(n-1)种跳法
- 假设第一次青蛙跳2级,那剩余n-2级,也就是还有f(n-2)种跳法
- ...
- 假设第一次青蛙跳n级,那剩余n-n级
- 总结下来就是 f(n) = f(n-1) + f(n-2) + f(n-3) +...+ f(0)
- 由于f(0) = 1,f(1) = 1,f(2) = 2f(1),f(3) = 2f(2),所以f(n) = 2f(n-1) = 2(n-1)
代码实现
public class Solution { public int JumpFloorII(int target) { if(target <= 0){ return 0; } return (int)Math.pow(2,target-1); } }
第十题
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
比如n=3时,2*3的矩形块有3种覆盖方法:
解题思路
这道题叫做矩形覆盖问题,其实和第7题,第8题,第9题差不多,这道题也是使用斐波那契数列解决
- 由于直接考虑整个矩形覆盖无从下手,那就考虑刚开始的地方,如果第一个2*1的小矩形竖着放(也就是还是2*1),那大矩形剩余2*(n-1),那就还有f(n-1)种覆盖方法
- 如果第一个小矩形横着放(也就变成1*2),那这个小矩形下面的空间只能再横着放一个小矩形,那大矩形剩余2*(n-2),也就还有f(n-2)种覆盖方法
- 综上所述,f(n) = f(n-1) + f(n-2)
代码实现
public class Solution { public int RectCover(int target) { if(target <= 0){ return 0; } if(target == 1){ return 1; } if(target == 2){ return 2; } int a = 1; int b = 2; int c = 0; for(int i = 3;i <= target;i++){ c = a + b; a = b; b = c; } return c; } }
第十一题
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
解题思路
这个题如果不仔细思考很简单,如果仔细思考,就比较复杂了,比如题中说的是一个整数,那这个整数是int类型,还是long类型的,虽然牛客网上代码限定是int类型,因为int类型无论是32位编译器还是64位编译器都是占用4位,也就是32个字节,如果是这样,那就简单了,因为负数在计算机中本身就是使用补码存储的,所以可以使用如下方式解决。
代码
直接获取整数的二进制表示,统计一下1的个数,我并不喜欢这种解决方式(这种时间复杂度是O(n))
public class Solution { public int NumberOf1(int n) { int t=0; char[]ch=Integer.toBinaryString(n).toCharArray(); for(int i=0;i<ch.length;i++){ if(ch[i]=='1'){ t++; } } return t; } }
还有一种就是通过位运算来统计,时间复杂度为O(m),其中m为1的个数
public class Solution { public int NumberOf1(int n) { int count = 0; while(n!= 0){ count++; n = n & (n - 1); } return count; } }
由于我在第一次做这个题的时候,并不知道怎么获取计算机中整数二进制表示,而且没有想到使用位运算,想了一种非常复杂的方法,先贴在这里,方便以后看
import java.util.Stack; public class Solution { public int NumberOf1(int n) { if (n == 0){ return 0; } int bark = n; n = Math.abs(n); Stack<Integer> stack = new Stack(); while(n != 0){ int result = n % 2; if(result == 0){ stack.push(0); n = n/2; }else{ stack.push(1); n = (n - result)/2; } } int result = 0; int count = 0; if (bark > 0){ while(!stack.isEmpty()){ result = (int)stack.pop(); if(result == 1){ count++; } } }else{ int[] array = new int[32]; int length = stack.size(); for(int i=0;i<array.length;i++){ if(array.length - i == stack.size()){ result = (int)stack.pop(); if(result == 1){ array[i] = 0; }else{ array[i] = 1; } }else{ array[i]=1; } } for(int i=array.length-1;i>=0;i--){ if(array[i]==0){ array[i] = 1; break; }else{ array[i]=0; if(i-1<0){ return -1; }else{ if(array[i-1] == 0){ array[i-1] = 1; break; } } } } for(int i=0;i<array.length;i++){ if(array[i]==1){ count++; } } } return count; } }