• [Hello World] 二分查找笔记



    活动地址:CSDN21天学习挑战赛

    一、介绍

    1.1 定义

    二分查找(Binary Search)也称折半查找,它是一种效率较高的查找方法。

    1.2 前提条件

    数列必须有序,对于无序数列,必须先进性排序才能用二分查找。

    1.3 原理

    检查一定区间内有序元素的中间位置,将其与所查找元素进行比较,如果大于所找元素,继续在左半区间查找,如果小于所找元素,则在右半区间查找,重复上述过程,直到找到所找元素或查找失败。

    1.4 局限性

    1. 需要操作有序数列
    2. 由于需要根据下标随机访问,所以该算法依赖于数组
    3. 非常小和非常大的数列都不适合
      非常小可以使用顺序算法,非常大

    1.5 复杂度

    时间复杂度:O(lgn)
    空间复杂度:O(1)

    二、代码示例

    二分查找的实现需要注意区间的开闭问题,对于全闭空间,如[left, right],边界判断要使用等号。
    C++代码如下:

    int binarySearch(vector<int>& nums, target)
    {
    	int left = 0;
    	int right = num.size() - 1;
    	
    	while (left <= right)
    	{
    		int middle = left + ((right - left) / 2);
    		if (nums[middle] > target)
    		{
    			right = middle - 1;
    		}
    		else if (nums[middle] < target)
    		{
    			left = middle + 1;
    		}
    		else
    		{
    			return middle;
    		}
    	}
    	return -1
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    如果存在开区间,如[left, right),边界判断不使用等号。
    C++代码如下:

    int binarySearch(vector<int>& nums, target)
    {
    	int left = 0;
    	int right = num.size();
    	
    	while (left < right)
    	{
    		int middle = left + ((right - left) / 2);
    		if (nums[middle] > target)
    		{
    			right = middle;
    		}
    		else if (nums[middle] < target)
    		{
    			left = middle + 1;
    		}
    		else
    		{
    			return middle;
    		}
    	}
    	return -1
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    二、实践

    1. leetcode 704. 二分查找
    class Solution {
    public:
        int search(vector<int>& nums, int target) {
            int l = 0, r = nums.size()-1, mid = 0;
            while(l <= r){
                mid = (l + r) >> 1;
                if(nums[mid] > target) r = mid - 1;
                else if(nums[mid] < target) l = mid + 1;
                else return mid;
            }
            return -1;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. leetcode 34. 在排序数组中查找元素的第一个和最后一个位置
    class Solution { 
    public:
        int binarySearch(vector<int>& nums, int target, bool lower) {
            int left = 0, right = (int)nums.size() - 1, ans = (int)nums.size();
            while (left <= right) {
                int mid = (left + right) / 2;
                if (nums[mid] > target || (lower && nums[mid] >= target)) {
                    right = mid - 1;
                    ans = mid;
                } else {
                    left = mid + 1;
                }
            }
            return ans;
        }
    
        vector<int> searchRange(vector<int>& nums, int target) {
            int leftIdx = binarySearch(nums, target, true);
            int rightIdx = binarySearch(nums, target, false) - 1;
            if (leftIdx <= rightIdx && rightIdx < nums.size() && nums[leftIdx] == target && nums[rightIdx] == target) {
                return vector<int>{leftIdx, rightIdx};
            } 
            return vector<int>{-1, -1};
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    1. leetcode 35. 搜索插入位置
    class Solution {
        public int searchInsert(int[] nums, int target) {
            int n = nums.length;
            int left = 0, right = n - 1, ans = n;
            while (left <= right) {
                int mid = ((right - left) >> 1) + left;
                if (target <= nums[mid]) {
                    ans = mid;
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

  • 相关阅读:
    DirectX 12 学习笔记 -结构
    线性回归实现
    小白开始学习C++
    OpenShift 4 - 在 Jenkins 的 CI/CD 中用 RHACS 对镜像进行安全扫描
    使用资源编排 ROS 轻松部署高可用架构网站——以 WordPress 为例
    30+场技术论坛 1000+科技新品发布 今年云栖大会我们关注什么?
    JVM-垃圾回收概述
    nvm切换node版本
    mongodb使用x509认证
    移动&桌面均覆盖-免费使用,解锁VIP!
  • 原文地址:https://blog.csdn.net/maizousidemao/article/details/126112691