zoukankan      html  css  js  c++  java
  • 6.二分查找

    模板实现

    二分查找的情况如图所示

    模板如下:

    while (left <= right) {
        mid = (left + right) / 2;
        if (key ? arr[mid]) {
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return ?;
    

    只需要记住比较符号和返回值即可:
    根据要求值的位置,可以先确定比较符号,再确定返回值。
    比较符号:左<=, 右<;(左右方向)
    返回值: 左right, 右left;(位置,这个最好确定)

    #include <bits/stdc++.h>
    using namespace std;
    
    //二分查找
    int binarySearch(int arr[], int len, int key)
    {
        int left = 0;
        int right = len - 1;
        int mid;
    
        while (left <= right) {
            mid = (left + right) / 2;
            if (key < arr[mid]) {//key在左边
                right = mid - 1;
            } else if (arr[mid] < key) {//key在右边
                left = mid + 1;
            } else {
                return mid;
            }
        }
        return -1;
    }
    
    //1 查找最后一个小于key的元素
    int findLastLess(int arr[], int len, int key)
    {
        int left = 0;
        int right = len - 1;
        int mid;
    
        while (left <= right) {
            mid = (left + right) / 2;
            if (key <= arr[mid]) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return right;
    }
    
    //2 查找第一个大于等于key的元素
    int findFirstGreaterEqual(int arr[], int len, int key)
    {
        int left = 0;
        int right = len - 1;
        int mid;
    
        while (left <= right) {
            mid = (left + right) / 2;
            if (key <= arr[mid]) {
                right = mid - 1;
            }
            else {
                left = mid + 1;
            }
        }
        return left;
    }
    
    //3 查找最后一个小于等于key的元素
    int findLastLessEqual(int arr[], int len, int key)
    {
        int left = 0;
        int right = len - 1;
        int mid;
    
        while (left <= right) {
            mid = (left + right) / 2;
            if (key < arr[mid]) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return right;
    }
    
    //4 查找第一个大于key的元素
    int findFirstGreater(int arr[], int len, int key)
    {
        int left = 0;
        int right = len - 1;
        int mid;
    
        while (left <= right) {
            mid = (left + right) / 2;
            if (key < arr[mid]) {
                right = mid - 1;
            }
            else {
                left = mid + 1;
            }
        }
        return left;
    }
    
    //5 查找第一个与key相等的元素
    int findFirstEqual(int arr[], int len, int key)
    {
        int left = 0;
        int right = len - 1;
        int mid;
    
        while (left <= right) {
            mid = (left + right) / 2;
            if (key <= arr[mid]) {
                right = mid - 1;
            } else {//arr[mid] < key
                left = mid + 1;
            }
        }
        //arr[right] < key <= arr[left]
        //right是最后一个小于key的
        //left是第一个大于等于key的
        if (left < len && arr[left] == key) {
            return left;
        }
        return -1;
    }
    
    //6 查找最后一个与key相等的元素
    int findLastEqual(int arr[], int len, int key)
    {
        int left = 0;
        int right = len - 1;
        int mid;
    
        while (left <= right) {
            mid = (left + right) / 2;
            if (key < arr[mid]) {
                right = mid - 1;
            } else {//arr[mid] <= key
                left = mid + 1;
            }
        }
        //arr[right] <= key < arr[left]
        //right是最后一个小于等于key的
        //left是第一个大于key的
        if (right >= 0 && arr[right] == key) {
            return right;
        }
        return -1;
    }
    
    
    void test()
    {
    //  int a[] = {0, 1, 2, 3, 4, 5, 6};
        int a[] = {0, 1, 2, 2, 2, 5, 6};
        int len = 7;
        int key = 2;
    
        int index;
    
        int i;
        for (i = 0; i < len; ++i) {
            printf("%d ", i);
        }
        printf("
    ");
        for (i = 0; i < len; ++i) {
            printf("%d ", a[i]);
        }
        printf("
    ");
    
    //    index = binarySearch(a, 10, 2);
        printf("%d binarySearch
    ", binarySearch(a, len, key));
        printf("%d findLastLess
    ", findLastLess(a, len, key));
        printf("%d findFirstGreaterEqual
    ", findFirstGreaterEqual(a, len, key));
        printf("%d findLastLessEqual
    ", findLastLessEqual(a, len, key));
        printf("%d findFirstGreater
    ", findFirstGreater(a, len, key));
        printf("%d findFirstEqual
    ", findFirstEqual(a, len, key));
        printf("%d findLastEqual
    ", findLastEqual(a, len, key));
    }
    
    int main()
    {
        test();
        return 0;
    }
    

    旋转数组查找最小值

    class Solution:
        def minArray(self, numbers: List[int]) -> int:
            # 简单二分, 当m=e时无脑直接e-1...
            # 最后返回跳出循环后的numbers[s]
            # 注意m<e时要把e设为m, 因为最小值可能就是m
            s, e = 0, len(numbers) - 1
            while s < e:
                m = (s + e) >> 1
                if numbers[m] < numbers[e]:
                    # m可能是最小值, 不能排除它
                    e = m
                elif numbers[m] > numbers[e]:
                    # m一定不是最小值, 排除它
                    s = m + 1
                else:
                    # 退化的情况
                    e -= 1
            return numbers[s]
    

    参考链接:
    二分查找的总结,这个链接绝了

  • 相关阅读:
    实现三联tab切换特效
    SQL Server对数据进行添加
    SmartUpload实现文件上传
    JavaScript图片轮播,举一反三
    SQL Server对数据进行删除
    用SQL Server查询所有数据并显示
    SQL Server日期格式化
    用SQL Server验证用户名和密码
    SQL Server存储过程作业(三)
    SQL Server存储过程作业(二)
  • 原文地址:https://www.cnblogs.com/wangzi199/p/13409126.html
Copyright © 2011-2022 走看看