• 二分查找法


    一、基本思路

    #include <iostream>
    #include <cassert>
    #include <ctime>
    
    using namespace std;
    
    template<typename T>
    int binarySearch(T arr[], int n, T target){
        int l = 0, r = n-1;
        while( l <= r ){
            int mid = l + (r-l)/2;
            if( arr[mid] == target )
                return mid;
            if( arr[mid] > target )
                r = mid - 1;
            else
                l = mid + 1;
        }
        return -1;
    }
    //测试代码
    int main() {
        int n = 1000000;
        int* a = new int[n];
        for( int i = 0 ; i < n ; i ++ )
            a[i] = i;
        clock_t startTime = clock();
        for( int i = 0 ; i < 2*n ; i ++ ){
            int v = binarySearch(a, n, i);
            if( i < n )
                assert( v == i );
            else
                assert( v == -1 );
        }
        clock_t endTime = clock();
        cout << "Binary Search (Without Recursion): " << double(endTime - startTime) / CLOCKS_PER_SEC << " s"<<endl;
        delete[] a;
        return 0;
    }

    二、leetcode有关题型:

    704-二分查找

    思路:纯二分查找

     69-x的平方根

    思路:理解根为以x为最右的区间值的查找

     35-搜索插入位置

    思路:理解为找到左边为最大值的插入位置

    153-寻找旋转排序数组中的最小值

    思路:可以设置最小值为最右边界值,然后二分查找到该值

    154-

    思路:153题的升级版,需要考虑重复元素的存在,可以考虑去除重复后继续查找

    287-寻找重复数

    思路:求出mid值后,统计所有小于mid的重复值个数,然后统计值比mid小就在右2半区间,否则就在左半区间,此时的最右值就是我们要求的答案

    1095-山脉数组中查找目标值

    思路:先二分查找找出最大值,然后再分左右两边查找目标值,使用三次二分查找

    /**
     * // 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 findInMountainArray(int target, MountainArray &mountainArr) {
            int l = 0, r = mountainArr.length() - 1;
            
            while (l < r) {
                int mid = l + (r - l)/2;
                if (mountainArr.get(mid) < mountainArr.get(mid + 1)) {
                    l = mid + 1;
                } else {
                    r = mid;
                }
            }
        
            int peak = l;
            if (target > mountainArr.get(peak)) return -1;
        
            // 先找左边
            l = 0, r = peak;
            while (l <= r) {
                int mid = l + (r - l)/2;
                if (target == mountainArr.get(mid)) {
                    return mid;
                } else if (target < mountainArr.get(mid)) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
        
            // 在右边找。
            l = peak + 1, r = mountainArr.length() - 1;
            while (l <= r) {
                int mid = l + (r - l)/2;
                if (target == mountainArr.get(mid)) {
                    return mid;
                } else if (target > mountainArr.get(mid)) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
        
            return -1;
        }
    };
    

      

  • 相关阅读:
    arduino电子艺术PWM直流电机电调实验
    横坐标轴移动位置
    将不才则三军倾
    Source Insight常用快捷键及注释快捷键设置
    dos2unix批量转换的脚本
    win8: ListView
    win8: Asynchronous Programming in JavaScript with “Promises”
    WindJS 中的$await
    iphone:关于沙盒 存储路径
    win8: hello gril
  • 原文地址:https://www.cnblogs.com/darklights/p/11718056.html
Copyright © 2020-2023  润新知