小白上楼梯(递归设计)
小白正在上楼梯,楼梯有n阶台阶,小白依次可以上1阶,2阶或者3阶,实现一个方法,计算小白有多少中走楼梯的方式
_n
...
_6
_5
_4
_3
_2
_1
0
f(n)=f(n-1)+f(n-2)+f(n-3)//递归公式
private static int f(int n){
if(n==0)return 1;
if(n==1)return 1;
if(n==2)return 2;
return f(n-1)+f(n-2)+f(n-3);//拿第三个台阶比例,从0->3,从1->3,从2->3(0->1->2,0->2)
}
旋转数组的最小数字(改造二分法)
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递归排序的数组的旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1
//有序就可以用二分法
3 4 5 1 2
左侧有序,右侧无序
4 5 1 2 3
左侧无序,右侧有序
最小值始终在无序的一侧
每次二分都找无序的一次即可
拿3 4 5 1 2为例
3 4 5 1 2->5 1 2->5 1
当剩两个元素时,结束二分,最小值总在最大值左侧
static int min(int[] arr){
int begin=0;
int end=arr.length-1;
//考虑没有旋转这种特殊的旋转
if(arr[begin]<arr[end])return arr[begin];
//begin和end指向相邻元素,退出
while(begin+1==end){
int mid=begin+((end-begin)>>1);
//要么左侧有序,要么右侧有序
if(arr[mid]>=arr[begin]){//左侧有序
begin=mid;
}else{
end=mid;
}
}
return arr[end];
}
遇到此种情况,则上述方法不行
0 1 1 1 1
1 1 1 0 1
在有空字符串的有序字符串数组中查找
有个排序后的字符串数组,其中散布着一些空字符串,编写一方法,找出给定字符串(肯定不是空字符串)的索引
a "" ac "" ad "" ba
private static int indexOf(String[] arr,String p){
int begin=0;//字符串是个有序序列,套用二分模板
int end=arr.length-1;
while(begin<=end){
int indexofMid=begin+((end-begin)>>1);
while(arr[indexOfMid],equals(""))//空串就往往前走,直到不是空串则退出
indexOFMid++;
if(indexOfMid>end)
//若是到中值为”“,向右移一位,若是indexOfMid不断右移,超过了end,则二分方法找不到
return -1;
if(arr[indexOfMid].compareTo(p)>0){//在左半区间
end=indexOfMid-1;
}else if(arr[indexOfMid].compareTo(p)<0){
begin=indexOfMid+1;
}else{
return indexOfMid;
}
}
return 0;
}
最长连续递增子序列(部分有序)
(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)
可用双指针,左右双指针,左指针指向每一位,每到一位,判断后面是否递增,若递增,右指针右移一位,直到递增结束,最后左指针到右指针的距离便为递增序列的个数,记录最长子序列即可求出答案
static void maxseq(int[] arr,int length){
int l.r,count=0;
for(int left=0;left<arr.length;left++){
for(int right=left;right<arr.length;right++){
if(arr[right]>arr[right+1]) break;
}
if(right-left+1>count)//始终更新最大值和最长递增序列左右指针
{count=right-left+1;
l=left;
r=right;
}
}
for(int i=l;i<=right;i++){
System.out.println(arr[i]);
}
}
设计一个高效的求a的n次幂的算法
//o(n)
static void int pow(int a,int n){
int res=1;
for(int i=0;i<n;i++){
res*=a;
}
return res;
}
//o(lgn)
//快速幂
private static int pow(int a,int n){
int res=a;//因为要用递归,a的值不能变
int ex=1;//当前a已乘的次方,指数
while((ex<<1)<n){
//如果ex<<1大于n就退出,但是还剩下一些次方,没有乘,可以用递归解决
res=res*res;
ex<<=1;
}
return res*pow(n-ex);//差n-ex剩余没有乘上的次方
}