首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >二分问题-LeetCode 33、34(上下边界,二分查找)

二分问题-LeetCode 33、34(上下边界,二分查找)

作者头像
算法工程师之路
发布于 2019-09-19 07:38:48
发布于 2019-09-19 07:38:48
1K00
举报
运行总次数:0
作者:TeddyZhang,公众号:算法工程师之路

DFS基础问题:LeetCode #33 #34

1

编程题

【LeetCode #33】搜索旋转排序数组

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。 你的算法时间复杂度必须是 O(log n) 级别。

示例 1: 输入: nums = [4,5,6,7,0,1,2], target = 0 输出: 4 示例 2: 输入: nums = [4,5,6,7,0,1,2], target = 3 输出: -1

解题思路:

由于是旋转排序数组,因此我们从中间切成两半,其中一半必定有序,而另外一半也是一个旋转排序数组,再次分割还是会产生一个有序和无序的数组! 因此我们开始第一次二分,计算得到mid,因此:

  • 如果(mid, r]有序,则判断target是不是在这个有序数组中,如果在,则选择右部分, l=mid+1。
  • 否则[l, mid)有序,然后接着判断target,并开始限定边界
  • 注意:计算mid最好使用l+(r-l)>>1, 而不是(l+r)>>1,因为l+r有可能超出数据类型的边界!造成不可知错误。

C++代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l = , r = nums.size() - ;
        while(l <= r){
            int mid = l + (r-l) / ;
            if (nums[mid] == target)  return mid;
            if(nums[mid] < nums[r]){   // 如果右半部分有序,直接二分
                if(nums[mid] < target && target <= nums[r])  l = mid + ;
                // 如果target落在有序部分,那么l=mid+1
                else  r = mid - ;
            }else{  // 如果右半部分不是有序的,那必定左半部分有序
                if(nums[mid] > target && target >= nums[l]) r = mid - ;
                else l = mid + ;
            }  
        }
        return -1;
    }
};

我们还可以对上述问题进行优化处理,合并两个判断语句即可!运行速度会提升很多的!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = , right = nums.size() - ;

        while (left <= right) {
            int mid = left + (right - left) / ;
            if (nums[mid] == target) {
                return mid;
            } else if ((nums[mid] >= nums[left] && nums[left] <= target && target < nums[mid]) ||
                       (nums[mid] < nums[left] && !(nums[mid] < target && target <= nums[right]))) {
                right = mid - ;
            } else {
                left = mid + ;
            }
        }

        return -1;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array

【LeetCode #34】在排序数组中查找元素的第一个和最后一个位置

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

你的算法时间复杂度必须是 O(log n) 级别。

如果数组中不存在目标值,返回 [-1, -1]。

示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 示例 2: 输入: nums = [5,7,7,8,8,10], target = 6 输出: [-1,-1]

解题思路:

在一个排序数组中查找某个元素的算法,我们很容易可以写出来寻找一个元素左边界的二分算法,即将target与mid相等时,将右边界r变为mid-1,向右移动即可! 那么怎么去查找某个元素的第一个和最后一个位置呢?很简单的思路,我们将左边界算法的查找目标target变化一下就可以了,第一次查找target,可以得到左边界的位置,第二次查找target+1,可能找到也可能找不到,但返回的都是最后位置+1的位置。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
     vector<int> searchRange(vector<int>& nums, int target) {
        int idx1 = lower_bound(nums, target);
        int idx2 = lower_bound(nums, target+)-1;
        if (idx1 < nums.size() && nums[idx1] == target)
            return {idx1, idx2};
        else
            return {-1, -1};
     }

    int lower_bound(vector<int>& nums, int target) {
        int l = , r = nums.size()-1;
        while (l <= r) {
            int mid = l+(r-l)/;
            if (nums[mid] < target)
                l = mid+;
            else
                r = mid-1;
        }
        return l;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法工程师之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
吃透二分查找—— LeetCode 第 33、34、35 题记
昨天没能完成 34,今天来补上。恰好第 35 题也是二分查找算法的应用,放到一起来记录。
TTTEED
2020/07/09
2K0
二分查找团灭力扣旋转排序数组系列
Leetcode 中有一系列旋转排序数组相关的问题,例如33. 搜索旋转排序数组、81. 搜索旋转排序数组 II、153. 寻找旋转排序数组中的最小值、154. 寻找旋转排序数组中的最小值 II 和面试题10.03 搜索旋转数组等,本文介绍通过二分查找团灭这一系列问题,供大家参考,希望能对大家有所帮助。
程序员小熊
2021/05/28
6620
二分查找团灭力扣旋转排序数组系列
LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
Michael阿明
2020/07/13
2.2K0
LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)
LeetCode 33. 搜索旋转排序数组(二分查找)
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
Michael阿明
2020/07/13
3420
LeetCode 33. 搜索旋转排序数组(二分查找)
深度解析算法之二分查找(2)
题目链接 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
Undoom
2025/04/20
2100
深度解析算法之二分查找(2)
Leetcode | 第4节:二分查找,归并排序
上一节我们说完了链表的一些高频题。那么这一节,我们会介绍一些二分查找和排序相关的题目。二分和排序本身不是很困难,但是还是有一些难题需要一些技巧才能解决(倒也不是完全毫无头绪的那种),所以这一篇文章,我们除了基本内容外,也会花一些时间介绍一下技巧性的内容。
学弱猹
2021/08/10
5980
Leetcode | 第4节:二分查找,归并排序
面试前必知必会二分查找及其变种
今天给大家带来的是二分查找及其变种的总结,大家一定要看到最后呀,用心满满,废话不多说,让导演帮我们把镜头切到袁记菜馆吧!
公众号袁厨的算法小屋
2020/12/19
1.4K0
LeetCode-算法-二分查找-第15天
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。
布衣者
2021/09/07
3040
【算法专题】二分查找
题目:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 - 1。
YoungMLet
2024/03/01
2270
【算法专题】二分查找
【优选算法篇】寻找隐藏的宝藏:用二分查找打开算法世界的大门(上篇)
二分查找(Binary Search)是一种经典的算法,广泛应用于计算机科学中,尤其在处理有序数据时。其重要性体现在以下几个方面:
熬夜学编程的小王
2024/12/24
3260
【优选算法篇】寻找隐藏的宝藏:用二分查找打开算法世界的大门(上篇)
穿了好几个马甲,差点没认出来是二分查找
今天给大家带来的是二分查找及其变种的总结,大家一定要看到最后呀,非常非常用心的一篇文章,废话不多说,让导演帮我们把镜头切到袁记菜馆吧!
公众号袁厨的算法小屋
2020/12/22
6650
穿了好几个马甲,差点没认出来是二分查找
二分查找总结
二分查找是在每次匹配后,将查找的空间一分为二的算法,二分查找应该是有序的数组进行查找.
Tim在路上
2020/08/04
5370
【优选算法篇】在分割中追寻秩序:二分查找的智慧轨迹
给定一个升序排列的整数数组 nums,和一个目标值 target。如果 target 在数组中存在,返回其下标;否则,返回 -1。
半截诗
2024/10/22
3910
【刷题】 二分查找入门
总有一天,你会站在最亮的地方,活成自己曾经渴望的模样—— 苑子文 & 苑子豪《我们都一样 年轻又彷徨》
叫我龙翔
2024/04/02
1840
【刷题】 二分查找入门
【二分算法】——8个题目让你找到二分算法的感觉势如破竹
https://leetcode.cn/problems/binary-search/
用户11286421
2024/10/12
6350
【二分算法】——8个题目让你找到二分算法的感觉势如破竹
【oj刷题】二分查找篇:二分查找算法的原理和应用场景
二分查找一般是基于有序数组的,通过比较目标值与中间元素的大小关系,来决定是在数组的左侧还是右侧继续搜索。
GG Bond1
2024/09/21
6860
【oj刷题】二分查找篇:二分查找算法的原理和应用场景
LeetCode题目33:搜索旋转排序数组
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
二环宇少
2020/08/13
5630
LeetCode题目33:搜索旋转排序数组
[算法总结] 二分查找
二分查找法作为一种常见的查找方法,将原本是线性时间提升到了对数时间范围,大大缩短了搜索时间,但它有一个前提,就是必须在有序数据中进行查找。
尾尾部落
2018/09/04
8470
【每日一题】33. Search in Rotated Sorted Array
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
公众号-不为谁写的歌
2020/08/11
4010
【每日一题】33. Search in Rotated Sorted Array
二分查找的通用模板
二分查找适用于对于有序数组的精确查找,例如从一个有序数组中找到指定元素的索引,可将时间复杂度从普通枚举的 O(n) 降至 O(log n) ,前提是数组必须是有序的,否则是没有办法使用二分查找的。二分查找的思想虽然简单,不过在实现过程中会有很多细节问题需要注意,例如判断循环是用left < right还是用left <= right,right是取最右的元素还是取数组的边界。本文想通过七个例题,约定一种规则或是模板,从此让写二分查找不再出现模棱两可的局面。
兜兜转转
2023/03/08
1.1K0
推荐阅读
相关推荐
吃透二分查找—— LeetCode 第 33、34、35 题记
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档