文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C++如何实现在有序数组中查找元素的第一个和最后一个位置

2023-06-20 16:02

关注

这篇文章主要讲解了“C++如何实现在有序数组中查找元素的第一个和最后一个位置”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++如何实现在有序数组中查找元素的第一个和最后一个位置”吧!

Find First and Last Position of Element in Sorted Array 在有序数组中查找元素的第一个和最后一个位置

Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

Example 1:

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

Example 2:

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]

这道题让我们在一个有序整数数组中寻找相同目标值的起始和结束位置,而且限定了时间复杂度为 O(logn),这是典型的二分查找法的时间复杂度,所以这里也需要用此方法,思路是首先对原数组使用二分查找法,找出其中一个目标值的位置,然后向两边搜索找出起始和结束的位置,代码如下:

解法一:

class Solution {public:    vector<int> searchRange(vector<int>& nums, int target) {        int idx = search(nums, 0, nums.size() - 1, target);        if (idx == -1) return {-1, -1};        int left = idx, right = idx;        while (left > 0 && nums[left - 1] == nums[idx]) --left;        while (right < nums.size() - 1 && nums[right + 1] == nums[idx]) ++right;        return {left, right};    }    int search(vector<int>& nums, int left, int right, int target) {        if (left > right) return -1;        int mid = left + (right - left) / 2;        if (nums[mid] == target) return mid;        if (nums[mid] < target) return search(nums, mid + 1, right, target);        else return search(nums, left, mid - 1, target);    }};

可能有些人会觉得上面的算法不是严格意义上的 O(logn) 的算法,因为在最坏的情况下会变成 O(n),比如当数组里的数全是目标值的话,从中间向两边找边界就会一直遍历完整个数组,那么下面来看一种真正意义上的 O(logn) 的算法,使用两次二分查找法,第一次找到左边界,第二次调用找到右边界即可,具体代码如下:

解法二:

class Solution {public:    vector<int> searchRange(vector<int>& nums, int target) {        vector<int> res(2, -1);        int left = 0, right = nums.size();        while (left < right) {            int mid = left + (right - left) / 2;            if (nums[mid] < target) left = mid + 1;            else right = mid;        }        if (right == nums.size() || nums[right] != target) return res;        res[0] = right;        right = nums.size();        while (left < right) {            int mid = left + (right - left) / 2;            if (nums[mid] <= target) left = mid + 1;            else right = mid;        }        res[1] = right - 1;        return res;    }};

其实我们也可以只使用一个二分查找的子函数,来同时查找出第一个和最后一个位置。如何只用查找第一个大于等于目标值的二分函数来查找整个范围呢,这里用到了一个小 trick,首先来查找起始位置的 target,就是在数组中查找第一个大于等于 target 的位置,当返回的位置越界,或者该位置上的值不等于 target 时,表示数组中没有 target,直接返回 {-1, -1} 即可。若查找到了 target 值,则再查找第一个大于等于 target+1 的位置,然后把返回的位置减1,就是 target 的最后一个位置,即便是返回的值越界了,减1后也不会越界,这样就实现了使用一个二分查找函数来解题啦,参见代码如下:

解法三:

class Solution {public:    vector<int> searchRange(vector<int>& nums, int target) {        int start = firstGreaterEqual(nums, target);        if (start == nums.size() || nums[start] != target) return {-1, -1};        return {start, firstGreaterEqual(nums, target + 1) - 1};    }    int firstGreaterEqual(vector<int>& nums, int target) {        int left = 0, right = nums.size();        while (left < right) {            int mid = left + (right - left) / 2;            if (nums[mid] < target) left = mid + 1;            else right = mid;        }        return right;    }};

感谢各位的阅读,以上就是“C++如何实现在有序数组中查找元素的第一个和最后一个位置”的内容了,经过本文的学习后,相信大家对C++如何实现在有序数组中查找元素的第一个和最后一个位置这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯