• Search for a Range


      关于二分法搜索的题目,真是多得不能再多。当然标准的二分搜索是核心,在此之上作变化。

      常见的有搜索目标值中index最小的,搜索目标值中index最大的。常见的思路是先用二分搜索找到目标值,再往左或者往右依次比较。然而,对于有些输入,比如[1,1,1,1,1,1]这样的数组,算法就退化成了O(n)了。正确的方法仍然是使用二分。

      就这题而言,可以分作三部:先找最左边的,再找最右边的,最后合并,就是结果。算法复杂度nlog(n)。

      

    class Solution {
    public:
        vector<int> searchRange(int A[], int n, int target) {
            vector<int> res;
            if(n==0)
                return res;
            int left=searchRangeLeft(A,n,target);
            int right=searchRangeRight(A,n,target);
            if(left!=-1)
                return res;
            res.push_back(left);
            res.push_back(right);
            return res;
        }
    
        int searchRangeRight(int A[],int n,int target){
            int l=0;
            int r=n-1;
            int m;
            int res=n;
            
            while(l<=r)
            {
                m=(l+r)/2;
                if(A[m]==target){
                    if(m<res)
                        res=m;
                    r=m-1;
                }
                else if(target<A[m])
                {
                    r=m-1;
                }
                else
                {
                    l=m+1;
                }
            }
            if(res==n)
                res=-1;
            return res;
        }
    
        int searchRangeLeft(int A[],int n,int target){
            int l=0;
            int r=n-1;
            int m;
            int res=-1;
            
            while(l<=r)
            {
                m=(l+r)/2;
                if(A[m]==target){
                    if(m>res)
                        res=m;
                    l=m+1;
                }
                else if(target<A[m])
                {
                    r=m-1;
                }
                else
                {
                    l=m+1;
                }
            }
            return res;
        }
    };

      还看到另外一种解法,只需要求目标值的最大index。

      

    class Solution {  
    public:  
        vector<int> searchRange(int A[], int n, int target) {  
            // Start typing your C/C++ solution below  
            // DO NOT write int main() function  
            vector<int> res(2);  
            res[0] = binarySearch(A, n, target - 1) + 1;  
            res[1] = binarySearch(A, n , target);  
            if(res[1] == -1 || A[res[1]] != target){  
                res[0] = -1;  
                res[1] = -1;  
            }  
            return res;  
        }  
        int binarySearch(int A[], int n, int target){  
            int l = 0;  
            int r = n -1;  
            int m = (l+r)/2;  
            int ret = -1;  
            while(l<=r){  
                if(A[m] > target){  
                    r = m - 1;  
                    m = (l+r)/2;  
                }  
                else{  
                    ret = m;  
                    l = m + 1;  
                    m = (l+r)/2;  
                }  
            }  
            return ret;  
        }  
    };  

      这一解法我持保留态度,因为它的binarySearch函数返回的结果其实是不明确的,也就是说,需要对返回的结果作进一步的判断才能确定是否找到了目标值。如果从工程的角度而言,这样无异于给未来埋了一个定时炸弹。

  • 相关阅读:
    Unix/Linux环境C编程入门教程(23) 字符数字那些事儿
    Unix/Linux环境C编程入门教程(22) C/C++如何获取程序的运行时间
    如何定义函数模板
    Unix/Linux环境C编程入门教程(21) 各个系统HelloWorld跑起来效果如何?
    为什么使用模板
    CC++初学者编程教程(16) 搭建Xcode cocos2dx开发环境
    delete noprompt archivelog 报错ORA-00245,RMAN-08132
    RMAN-03002、RMAN-06059
    RAC RMAN 备份 RMAN-03009 ORA-19504 ORA-27040 RMAN-06012 channel c3 not allocated 错误分析
    RMAN备份到NFS,报错 ORA-27054
  • 原文地址:https://www.cnblogs.com/zhizhizhiyuan/p/3802316.html
Copyright © 2020-2023  润新知