• 【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;
        }
    };
  • 相关阅读:
    js 学习的地址;
    HTML onmousedown 事件属性 关于鼠标按键的问题;
    contextmenu="supermenu" 属性的应用 右键菜单打开和保存功能
    gulp自动化ES6转ES5
    angularjs获取元素以及angular.element()用法
    gulp学习总结
    Git 代码管理常用命令
    SpringMVC基于代码的配置方式(零配置,无web.xml)
    [Android Studio 权威教程]AS 中配置强大的版本号管理系统(Git、SVN、等)
    SVM支持向量机
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4514672.html
Copyright © 2020-2023  润新知