【基础算法练习】二分模板

二分模板题

704. 二分查找,这道题目是最经典的二分查找,使用于任何模板(如果你学的模板连这道题都套不上,那大概是模板有问题)

34. 在排序数组中查找元素的第一个和最后一个位置,一个合格的二分模板,需要能够应对这道题目的两种二分情况,我待会儿也会以这道题作为例题

二分的思想

我学算法也有一年了,二分相关的题目刷了也有 20 道以上,二分的模板也学了不下于 3 套,每一套都很有道理,但做他们选的题目是做对了,当遇到野生的二分题目的时候,时常失灵

我自己也在努力总结二分的本质,之前我一直认为二分的本质就是寻找单调性,但似乎并不是这样的,有单调性的题目确实一定可以用二分,但有些没有单调性的题目也可以用二分

其实二分的本质并不是单调性,当我们能将数据分成两个区间,一个区间不符合要求可以舍去,一个区间包含我们需要的答案,需要保留,这样的题目就能够使用二分

C++ 版本的二分

整数二分模板

模板一:用于左半区间不存在答案,而右半区间存在答案的情况,也就是在 [ left,mid ],[ mid + 1,right ]

int l = 0, r = n - 1;
while (l < r) {
   
    int mid = l + r >> 1;
    if (check(mid)) r = mid;
    else l = mid + 1;
}

模板二:用于左半区间存在答案,而右半区间不存在答案的情况,也就是在 [ left,mid - 1 ],[ mid,right ]

 int l = 0, r = n - 1;
 while (l < r) {
   
     int mid = l + r + 1 >> 1;
     if (check(mid)) l = mid;
     else r = mid - 1;
 }

模板记忆方法:有 - 1,那求 mid 的时候就需要 + 1

Golang 版本的二分

整数二分模板

模板一:用于左半区间不存在答案,而右半区间存在答案的情况,也就是在 [ left,mid ],[ mid + 1,right ]

l, r := 0, len(nums)-1
for l < r {
   
    mid := l+(r-l)/2
    if check(mid) {
   
        r = mid
    } else {
   
        l = mid + 1
    }
}

模板二:用于左半区间存在答案,而右半区间不存在答案的情况,也就是在 [ left,mid - 1 ],[ mid,right ]

l, r = 0, len(nums)-1
for l < r {
   
    mid := l+(r-l+1)/2
    if check(mid) {
   
        l = mid 
    } else {
   
        r = mid - 1
    }
}

例题:在排序数组中查找元素的第一个和最后一个位置

题目链接:34. 在排序数组中查找元素的第一个和最后一个位置

题目描述

C++ 版本代码

class Solution {
   
public:
    vector<int> searchRange(vector<int>& nums, int target) {
   
        if (nums.size() == 0) return {
   -1, -1};
        vector<int> ans;
        int l = 0, r = nums.size() - 1;
        while (l < r) {
   
            int mid = l + r >> 1;
            if (nums[mid] >= target) r = mid;
            else l = mid + 1;
        }
        
        if (nums[l] != target) return {
   -1, -1};
        ans.push_back(l);

        l = 0, r = nums.size() - 1;
        while (l < r) {
   
            int mid = l + r + 1 >> 1;
            if (nums[mid] <= target) l = mid;
            else r = mid - 1;
        }
        ans.push_back(l);
        
        return ans;
    }
};

Golang 版本代码

func searchRange(nums []int, target int) (ans []int) {
   
    if len(nums) == 0 {
   
        return []int{
   -1, -1}
    }
    l, r := 0, len(nums)-1
    for l < r {
   
        mid := l+(r-l)/2
        if nums[mid] >= target {
   
            r = mid
        } else {
   
            l = mid + 1
        }
    }
    if nums[l] != target {
   
        return []int{
   -1, -1}
    }
    ans = append(ans, l)
    l, r = 0, len(nums)-1
    for l < r {
   
        mid := l+(r-l+1)/2
        if nums[mid] <= target {
   
            l = mid 
        } else {
   
            r = mid - 1
        }
    }
    ans = append(ans, l)
    return ans
}

相关推荐

  1. 算法基础二分查找

    2024-01-24 11:44:02       13 阅读
  2. 基础算法练习】前缀和与差分模板

    2024-01-24 11:44:02       34 阅读
  3. 天秀基础算法 - 二分查找和二分答案

    2024-01-24 11:44:02       18 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-24 11:44:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-24 11:44:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-24 11:44:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-24 11:44:02       18 阅读

热门阅读

  1. transformer beginner

    2024-01-24 11:44:02       35 阅读
  2. 【从浅到深的算法技巧】链表 补

    2024-01-24 11:44:02       29 阅读
  3. Hive之set参数大全-13

    2024-01-24 11:44:02       24 阅读
  4. 系统移植及相关介绍

    2024-01-24 11:44:02       28 阅读
  5. RabbitMQ

    RabbitMQ

    2024-01-24 11:44:02      26 阅读
  6. Vue3-在HTML标签、组件标签上使用v-model

    2024-01-24 11:44:02       29 阅读
  7. Deepin基本环境查看(一)【基本信息】

    2024-01-24 11:44:02       36 阅读
  8. 百度搜索智能精选是什么东西、怎么加入?

    2024-01-24 11:44:02       31 阅读
  9. 美易官方:小米汽车交付时间传闻被官方辟谣

    2024-01-24 11:44:02       29 阅读
  10. CSS高级技巧导读

    2024-01-24 11:44:02       32 阅读