蓝桥杯算法基础(18):(五道小题)java版

本文介绍了递归设计在解决上楼梯问题中的应用,涉及递归公式、旋转数组的最小值查找、有序数组中非空字符串的索引定位,以及最长连续递增子序列的寻找。同时探讨了高效计算幂运算的方法,包括基础递归和快速幂算法。
摘要由CSDN通过智能技术生成

小白上楼梯(递归设计)

小白正在上楼梯,楼梯有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剩余没有乘上的次方
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值