首页 > 其他分享 >【34. 在排序数组中查找元素的第一个和最后一个位置】

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

时间:2024-07-04 23:01:31浏览次数:20  
标签:leftBorder target nums int 34 查找 数组 排序 left

题目:

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109


思路:

target在数组中有如下三种情况:

  1. target 在数组范围的右边或者左边,例如数组{3, 4, 5},target为2或者数组{3, 4, 5},target为6,此时应该返回{-1, -1}。
  2. target 在数组范围中,且数组中不存在target,例如数组{3,6,7},target为5,此时应该返回{-1, -1}。
  3. target 在数组范围中,且数组中存在target,例如数组{3,6,7},target为6,此时应该返回{1, 1}
    这三种情况都考虑到,说明就想的很清楚了。

采用二分法寻找target在数组里的左右边界,为了让代码清晰,分别写两个二分来寻找左边界和右边界。计算出来的左边界是不包含target的左边界,右边界同理。

在这里插入图片描述


代码:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int leftBorder = getLeftBorder(nums, target);
        int rightBorder = getRightBorder(nums, target);
        // leftBorder或rightBorder没被赋值,即target在nums数组范围的左边或右边
        if(leftBorder == -2 || rightBorder == -2) return {-1, -1};
        // target在nums数组范围中,且数组中存在target
        else if(rightBorder - leftBorder > 1) return {leftBorder + 1, rightBorder - 1};
        // target在nums数组范围中,但数组中不存在target
        else return {-1, -1};
    }

private:
    // 寻找左边界,不包含target
    int getLeftBorder(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        int leftBorder = -2;
        while(left <= right)
        {
            int middle = (left + right) / 2;
            if(target > nums[middle])
            {
                left = middle + 1;
            }
            else
            {
                right = middle - 1;
                leftBorder = right;
            }
        }
        return leftBorder;
    }

    // 寻找右边界,不包含target
    int getRightBorder(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        int rightBorder = -2;
        while(left <= right)
        {
            int middle = (left + right) / 2;
            if(target < nums[middle])
            {
                right = middle - 1;
            }
            else
            {
                left = middle + 1;
                rightBorder = left;
            }
        }
        return rightBorder;
    }
};


总结:

时间复杂度: O(logn) ,其中 n 为数组的长度。二分查找的时间复杂度为 O(logn),一共会执行两次,因此总时间复杂度为 O(logn)。
空间复杂度:O(1) 。只需要常数空间存放若干变量。

主要利用二分法查找target在数组范围中的左右边界,注意左右边界的查找条件。
因为最后left == right + 1;,所以leftBorder = right; rightBorder = left;


参考:

代码随想录

标签:leftBorder,target,nums,int,34,查找,数组,排序,left
From: https://blog.csdn.net/yuan_2001_/article/details/140191008

相关文章

  • 2024华为OD机试真题-根据IP查找城市-(C++/Python)-C卷D卷-200分
    2024华为OD机试题库-(C卷+D卷)-(JAVA、Python、C++)       题目描述某业务需要根据终端的IP地址获取该终端归属的城市,可以根据公开的IP地址池信息查询归属城市。地址池格式如下:城市名=起始IP,结束IP起始和结束地址按照英文逗号分隔,多个地址段采用英文分号分隔。比......
  • Solution - Atcoder AGC034F RNG and XOR
    考虑到这个边权是\(\oplus\),那么说明对于\((u,v)\),\(u\tov\)和\(v\tou\)的边权实质是相同的。那么对于\(0\tox\),就可以反过来,记录下对应的路径,从\(x\)开始走,那么第一次走到\(0\)的时候也就是从\(0\)第一次走到\(x\)的时候。于是就转化为了\(x\)为起点,第一次......
  • 使用go语言实现快速排序、归并排序、插入排序、冒泡排序、选择排序
    冒泡排序(BubbleSort):原理:比较相邻的元素,如果前一个比后一个大,就交换它们。这个过程会使得每一轮最大的元素“冒泡”到数组的末尾。时间复杂度:O(n^2)稳定性:稳定//BubbleSort函数使用冒泡排序算法对数组进行排序funcBubbleSort(arr[]int){ n:=len(arr) fori:=0......
  • 数据结构实验报告:查找
     一、实验目的1.掌握查找表的结构。2.掌握顺序查找、折半查找、二叉排序树查找和哈希查找。二、实验环境Windows10、VisualC++6.0三、实验任务1.编写程序实现顺序查找和折半查找。(1)顺序查找#include<stdio.h>#include<stdlib.h>#defineLIST_SIZE20typ......
  • 代码随想录算法训练营第八天|344.反转字符串、541.反转字符串Ⅱ、54.替换数字(卡码网
    344简单写个循环1classSolution{2public:3voidreverseString(vector<char>&s){4chartmp;5intlen=s.size();6for(inti=0;i<len/2;i++){7tmp=s[i];8s[i]=s[len-......
  • Java实现简单的冒泡排序
    Java实现简单的冒泡排序核心思想:把相邻的两个数字两两比较,当一个数字大于右侧相邻的数字时,交换他们的位置,当一个数字和他右侧的数字小于或等于的时候,不交换。(小到大排序)例如有数组{3,1,5,7,4,2}第一次排序{3,1,5,7,4,2}//开始{1,3,5,7,4,2}//1和3互换{1,3,5,7,4,2......
  • PHP桶排序:优化大数据集的高效算法解析与实践
    本文由ChatMoney团队出品本文将介绍一种在PHP中实现的高效排序算法——桶排序。通过使用桶排序,可以快速地对大数据集进行排序,特别是在数据分布均匀的情况下。文章将简要介绍桶排序的原理,并给出一个具体的PHP实现示例。一、桶排序原理桶排序(BucketSort)是一种将待排序数......
  • PHP桶排序:高效处理大数据集的算法解析与实现
    本文由ChatMoney团队出品本文将介绍一种在PHP中实现的高效排序算法——桶排序。通过使用桶排序,可以快速地对大数据集进行排序,特别是在数据分布均匀的情况下。文章将简要介绍桶排序的原理,并给出一个具体的PHP实现示例。一、桶排序原理桶排序(BucketSort)是一种将待排序数......
  • 【社招+校招】华为OD机试 - 运维日志排序(Java & JS & Python & C)
    鱼弦:公众号【红尘灯塔】,CSDN博客专家、内容合伙人、新星导师、全栈领域优质创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)运维日志排序算法实现(Java、JavaScript、Python、C、C++)算法概述运维日志......
  • Python基础小知识问答系列-字典列表根据字典key排序
    1.问题:    现有一个列表,需要根据字典元素的某个键,进行排序,该怎样实现?2.解决方法:    排序使用sorted函数,通过operator模块中的itemgetter函数实现指定key。示例:fromoperatorimportitemgetterfrompprintimportpprinttest_list=[1,3,6,2,9,......