zoukankan      html  css  js  c++  java
  • 百度面试题:求绝对值最小的数

    有一个已经排序的数组(升序),数组中可能有正数、负数或0,求数组中元素的绝对值最小的数,要求,不能用顺序比较的方法(复杂度需要小于O(n)),可以使用任何语言实现
    例如,数组{-20,-13,-4, 6, 77,200} ,绝对值最小的是-4。

    我们首先要看到,是已经排序的。 

    算法实现的基本思路三种情况:

    全负数 全正数 正负皆有
    1:取最右 时间复杂度为o(1)
    2:取最左 时间复杂度为o(1)
    3:二分查找0, 找到为最小,否则最后查找区间,左右取绝对值最小,时间复杂度为o(log2 n)

    这个二分查找还是有点难写的,如果arr[mid]为正,还要分arr[mid-1]是否为负,若为负,则一定是arr[mid]或arr[mid-1],若

    arr[mid-1]不为负,另high=mid-1;则半查找,从这点可以看出二分查找真是可以应用在许多场合。

    #include<iostream>
    #include<vector>
    #include<cmath>
    using namespace std;
    
    vector<int> getAbsMinVal(int arr[],int n)
    {
        vector<int> ret;
        if(n<2)
        {
            ret.push_back(arr[0]);
        }
        else
        {
            if(arr[n-1]<=0)//全为负数
            {
                ret.push_back(arr[n-1]);
            }
            else if(arr[0]>=0)
            {
                ret.push_back(arr[0]);
            }
            else
            {
                int low=0,high=n-1;
                while(low<=high)
                {
                    int mid=(low+high)/2;
                    if(arr[mid]==0)//中间位置为0.返回0
                    {
                        ret.push_back(arr[0]);
                    }
                    else if(arr[mid]>0)//中间位置为正数
                    {
                        if(arr[mid-1]<0)//前一个位置为负数
                        {
                            if(abs(arr[mid-1])==abs(arr[mid]))
                            {
                                ret.push_back(arr[mid-1]);
                                ret.push_back(arr[mid]);
                            }
                            else
                            {
                                ret.push_back(abs(arr[mid-1])<abs(arr[mid])?arr[mid-1]:arr[mid]);
                            }
                            break;
                        }
                        high=mid-1;
                    }
                    else //中间位置为负数
                    {
                        if(arr[mid+1]>0)//中间位置后一个为正数
                        {
                            if(abs(arr[mid])==abs(arr[mid+1]))
                            {
                                ret.push_back(arr[mid]);
                                ret.push_back(arr[mid+1]);
                            }
                            else
                            {
                                ret.push_back(abs(arr[mid])<abs(arr[mid+1])?arr[mid]:arr[mid+1]);
                            }
                            break;
                        }
                        low=mid+1;
                    }
                }
    
            }
        }//end else
        
        return ret;
    }
    
    int main()
    {
        int arr[]={-5,-4,2,3,5};
        vector<int> ret=getAbsMinVal(arr,sizeof(arr)/sizeof(arr[0]));
        for(int i=0;i<ret.size();i++)
            cout<<ret[i]<<ends;
    }
  • 相关阅读:
    linux(centos 6.4)下安装php memcache服务端及其客户端(详细教程)
    linux下swap问题处理
    mysql锁表查询,binlog日志清理
    Centos7上安装部署frp内网穿透
    配置frp实现内网穿透,域名再也不用备案了
    xp激活码 windows xp产品密钥 xp sp3专业版正版序列号
    windows不能使用剪贴板解决办法
    mysql多主一从配置
    给mysql的root %用户添加grant权限和创建的用户权限
    redis主从及集群配置密码
  • 原文地址:https://www.cnblogs.com/youxin/p/3313125.html
Copyright © 2011-2022 走看看