leetcode1095. 山脉数组中查找目标值

三分找极值点:https://blog.csdn.net/pi9nc/article/details/9666627

解题思路:

1.先用三分查找,找到极值点的位置pt

2.根据pt将数组分成两段,先对第一段[0,pt]二分查找target,找到立即返回

3.如果第一段没有找到target,则二分查找第二段[pt,arr.length-1]

这样满足查询不超过100次的要求吗?

答:三分 复杂度据说是2log3(n) ,二分复杂度是2log2(n)。

那么找极值点 最多需要查找 2log3(n) = 2log3(10000) ≈ 2*9 = 18 次

二分最多需要调用 2*log2(10000) ≈ 2*14 = 28 次

18 + 28 < 100,所以这个方案是满足要求的。

class Solution {
        int target;
        MountainArray mountainArr;
        public int findInMountainArray(int target, MountainArray mountainArr) {
            int len = mountainArr.length();
            int l = 0;
            int r = len-1;
            this.target = target;
            this.mountainArr=mountainArr;

         //1. 找极值点位置
            while(l+1<r)
            {
                int mid = mountainArr.get((l+r)/2);
                int mmid = mountainArr.get(((l+r)/2+r)/2);
                if(mid>mmid)
                {
                    r = ((l+r)/2+r)/2;
                }else{
                    l = (l+r)/2;
                }
            }
            int ll = mountainArr.get(l);
            int rr = mountainArr.get(r);
            int pt = ll>rr?l:r; 
            //pt是极值点
            //二分左边,找到返回
            int rs = two_divide(0,pt,true);
            if(rs!=-1) return rs;
            //二分右边
            rs = two_divide(pt+1,len-1,false);
            return rs;
        }

        private int two_divide(int l, int r,boolean up) {
            if(up){ //递增
                while(l<=r)
                {
                    int mid = (l+r)/2;
                    int mid_value = mountainArr.get(mid);
                    if(target<mid_value)
                    {
                        r = mid-1;
                    }else if(target>mid_value){
                        l = mid+1;
                    }else{
                        return mid;
                    }
                }
                return -1;
            }else{ //递减
                while(l<=r)
                {
                    int mid = (l+r)/2;
                    int mid_value = mountainArr.get(mid);
                    if(target>mid_value)
                    {
                        r = mid-1;
                    }else if(target<mid_value){
                        l = mid+1;
                    }else{
                        return mid;
                    }
                }
                return -1;
            }
        }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值