zoukankan      html  css  js  c++  java
  • LeetCode 1095 山脉数组中查找目标值(二分法)

    这道题大意是给出一个山脉数组,山脉数组的特点是长度不小于3,有一个数为山顶,这个数左边是递增数组,右边是递减数组,求出数组第一个出现值为target的数的下标,如果没有返回-1。数组最大长度能到10000,不能去遍历这个数组,因为最多只能访问100次数组,那么首先我想到的方法就是二分。整个数组又不是按序排列的,不能直接二分,应该先想办法去找到山顶,之后就好做了。首先把数组大概五等分,求出第二三四个点的数的值,这三个点可能出现有三种情况,第一个数>=第二个数且第二个数>=第三个数,第一个数<=第二个数且第二个数>=第三个数,第一个数<=第二个数且第二个数<=第三个数,这三种情况分别可以获取新的山顶所在的范围,详情见代码,注意这里的边界要处理好,否则可能陷入一直递归的情况。如果当前范围小于等于三,那么就可以确定山顶在范围中,依次验证每个点直到确定出山顶即可。确定完山顶之后其余的就简单了,在山顶左右两边分别二分去求是否出现target,如果出现了取较小的坐标值,否则返回-1。

    /**
     * // This is the MountainArray's API interface.
     * // You should not implement it, or speculate about its implementation
     * class MountainArray {
     *   public:
     *     int get(int index);
     *     int length();
     * };
     */
    
    class Solution {
    public:
        int len;
        int num[10005],vis[10005];
        int get_index(MountainArray &mountainArr,int left,int right)
        {
            if(right-left<=2)
            {
                for(int i=left;i<=right;i++)
                {
                    if(i<=0||i>=len-1) continue;
                    int save[3];
                    for(int j=-1;j<=1;j++)
                    {
                        if(!vis[i+j])
                        {
                            vis[i+j]=1;
                            num[i+j]=mountainArr.get(i+j);
                        }
                        save[j+1]=num[i+j];
                    }
                    if(save[1]>save[0]&&save[1]>save[2])
                        return i;
                }
                return -1;
            }
            int mid=(right+left)/2;
            int pos1=(mid+left)/2,pos2=mid,pos3=(mid+right)/2;
            int val1,val2,val3;
    //        cout<<pos1<<' '<<pos2<<' '<<pos3<<endl;
            if(!vis[pos1])
            {
                num[pos1]=mountainArr.get(pos1);
                vis[pos1]=1;
            }
            if(!vis[pos2])
            {
                num[pos2]=mountainArr.get(pos2);
                vis[pos2]=1;
            }
            if(!vis[pos3])
            {
                num[pos3]=mountainArr.get(pos3);
                vis[pos3]=1;
            }
            if(num[pos1]>=num[pos2]&&num[pos2]>=num[pos3])
            {
    //            cout<<1<<endl;
                return get_index(mountainArr,left,pos3-1);
            }  
            if(num[pos1]<=num[pos2]&&num[pos2]>=num[pos3])
            {
    //            cout<<2<<endl;
                return get_index(mountainArr,pos1+1,pos3-1);
            }
            if(num[pos1]<=num[pos2]&&num[pos2]<=num[pos3])
            {
    //            cout<<3<<endl;
                return get_index(mountainArr,pos1+1,right);
            }
            return -1;
        }
        int findInMountainArray(int target, MountainArray &mountainArr) {
            int ans=0;
            len=mountainArr.length();
            int i=get_index(mountainArr,0,len-1);
            int pos=-1;
            int left=0,right=i,mid;
            while(left<=right)
            {
                mid=(left+right)/2;
                if(!vis[mid])
                    num[mid]=mountainArr.get(mid);
                if(num[mid]<target)
                    left=mid+1;
                else if(num[mid]>target)
                    right=mid-1;
                else
                {
                    pos=mid;break;
                }
            }
            if(pos==-1)
            {
                left=i;
                right=len-1;
                while(left<=right)
                {
                    mid=(left+right)/2;
                    if(!vis[mid])
                        num[mid]=mountainArr.get(mid);
                    if(num[mid]>target)
                        left=mid+1;
                    else if(num[mid]<target)
                        right=mid-1;
                    else
                    {
                        pos=mid;break;
                    }
                }
            }
            return pos;
        }
    };
    
  • 相关阅读:
    iOS应用开发最佳实践
    Pywinauto 基于Win32 程序的自动化功能测试工具
    通信系统概论---电路交换与分组交换
    手动设置3G的wifi迷你无线路由
    作为一个软件测试工作者的思考
    中国人咋对“拼爹”现象如此诟病?
    HLS协议实现
    div:给div加滚动栏 div的滚动栏设置
    关于PCA算法的一点学习总结
    搜索引擎技术之概要预览
  • 原文地址:https://www.cnblogs.com/ambition-hhn/p/12804851.html
Copyright © 2011-2022 走看看