【Search for a Range】cpp

题目:

Given a sorted array of integers, 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].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

代码:

复制代码
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
            vector<int> ret;
            int pos = Solution::findPos(nums, target, 0, nums.size()-1);
            if ( pos==-1 )
            {
                ret.push_back(-1);
                ret.push_back(-1);
                return ret;
            }
            int l = Solution::findLeft(nums, target, 0, pos);
            ret.push_back(l);
            int r = Solution::findRight(nums, target, pos+1, nums.size()-1);
            ret.push_back(r);
            return ret;
    }
            static int findPos(vector<int>& nums, int target, int begin, int end)
        {
            if ( begin>end ) return -1;
            int mid = (begin+end)/2;
            if ( nums[mid]==target ) return mid;
            if ( nums[mid]>target )
            {
                return Solution::findPos(nums, target,begin,mid-1);
            }
            else
            {
                return Solution::findPos(nums, target, mid+1, end);
            }
        }
        static int findLeft(vector<int>& nums, int target, int begin, int end)
        {
            if ( begin>end ) return begin;
            int mid = (begin+end)/2;
            if ( nums[mid]<target )
            {
                return Solution::findLeft(nums, target, mid+1, end);
            }
            else
            {
                return Solution::findLeft(nums, target, begin, mid-1);
            }
        }
        static int findRight(vector<int>& nums, int target, int begin, int end)
        {
            if ( begin>end ) return end;
            int mid = (begin+end)/2;
            if ( nums[mid]>target )
            {
                return Solution::findRight(nums, target, begin, mid-1);
            }
            else
            {
                return Solution::findRight(nums, target, mid+1, end);
            }
        }
};
复制代码

tips:

按照常规的思路写的。

1. 首先二分查找target变量的某个位置,如果没有则直接返回-1

2. 确定有target变量了,则分左右两边找

  1)左侧:找最左边的target的元素

  2)右侧:找最右边的target元素

注意处理好边界的case。

=================================

学习了一种STL的写法 代码如下:

复制代码
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
            vector<int> ret;
            const int l = std::distance(nums.begin(), std::lower_bound(nums.begin(), nums.end(), target));
            const int u = std::distance(nums.begin(), std::upper_bound(nums.begin(), nums.end(), target));if (nums[l]!=target)
            {
                ret.push_back(-1);
                ret.push_back(-1);
            }
            else
            {
                ret.push_back(l);
                ret.push_back(u>0?u-1:0);
            }
            return ret;
    }
};
复制代码

非常简洁。

不知道为什么,在mac的sublime上coding时,prev() next() 这俩函数一直不让用。

=============================================

第二次过这道题,就是用二分查找的思路。找左边界,右边界。代码比第一次过的时候简洁一些。

复制代码
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
            vector<int> ret;
            int l = -1;
            int r = -1;
            int begin = 0;
            int end = nums.size()-1;
            // search for left bound
            while ( begin<=end )
            {
                int mid = (begin+end)/2;
                if ( nums[mid]==target )
                {
                    l = mid;
                    end = mid-1;
                }
                else if ( nums[mid]>target )
                {
                    end = mid-1;
                }
                else
                {
                    begin = mid+1;
                }
            }
            if ( l==-1 ) { ret.push_back(l); ret.push_back(r); return ret; }
            // search for right bound
            begin = l;
            end = nums.size()-1;
            while ( begin<=end )
            {
                int mid = (begin+end)/2;
                if ( nums[mid]==target )
                {
                    r = mid;
                    begin = mid+1;
                }
                else
                {
                    end = mid-1;
                }
            }
            ret.push_back(l);
            ret.push_back(r);
            return ret;
    }
};
复制代码

 

posted on   承续缘  阅读(172)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?

导航

< 2025年3月 >
23 24 25 26 27 28 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 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示