算法第四版1.4算法分析:习题1.4.20

利用1.1.18的思想,首先判断数组中是否存在局部极大值,

       如果不存在,说明数组单调,不是bitnoic 

       如果存在,在局部极大值划分开的两部分分别判断是否存在局部极小,若左半部分存在局部极小,表明左半部分不是单调递增;若右半部分存在局部极小,表明右半部分不是单调递减

 

import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;

public class E1_4_20 {
    public static void main(String[]args){
        //测试局部极大值程序
        int[]a={1,2,3,4,5,0};
        int index=LocalMaximum(a);
        StdOut.println("index="+index);
        //测试程序
        StdOut.println(isBitnoic(a));//a是
        int[]b={1,2,3,4,5,0,1};
        StdOut.println(isBitnoic(b));//b不是

        //Doubling Ratio test
        int N=125;
        double prev=timeTrial(N);
        for (N=250;true;N+=N){
            double now=timeTrial(N);
            StdOut.printf("N=%10d time=%7.5f ratio=%6.5f\n",N,now,now/prev);
            prev=now;
        }
    }
    public static double timeTrial(int N){
        int MAX=1000000;
        int[]a=new int[N];
        for (int i=0;i<N;i++)
            a[i]= StdRandom.uniform(-MAX,MAX);
        StopWatch time=new StopWatch();
        boolean isbitnoic=isBitnoic(a);
        double res=time.elapsedTime();
        return res;
    }
    public static boolean isBitnoic(int[]a){
        int maxIndex=LocalMaximum(a);
        if (maxIndex==-1) return false;//不存在局部极大值
        if (LocalMinimum(a,0,maxIndex)!=-1||LocalMinimum(a,maxIndex,a.length-1)!=-1)
            //极大值划分开的两部分只要有一个存在局部极小值,表明那部分不是单调的
            return false;
        else
            return true;
    }

    public static int LocalMaximum(int[]a){
        int lo=0;
        int hi=a.length-1;
        while (lo<hi){
            int mid=(lo+hi)/2;
            if (mid-1<0||mid+1>=a.length)
                return -1;
            if      (a[mid]<a[mid-1])   hi=mid-1;
            else if (a[mid]<a[mid+1])   lo=mid+1;
            else return mid;
        }
        return -1;
    }
    public static int LocalMinimum(int[]a,int left,int right){
        //判断数组a的lo到hi区域是否存在局部极小值
        int lo=left;
        int hi=right;
        while (lo<hi){
            int mid=(lo+hi)/2;
            if (mid-1<left||mid+1>right)    return -1;
            if (a[mid]>a[mid-1])            hi=mid-1;
            else if (a[mid]>a[mid+1])       lo=mid+1;
            else return mid;
        }
        return -1;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值