leetcode34. Find First and Last Position of Element in Sorted Array

题目:leetcode34

这题目言简意赅,看标题就可以了,就是找出一个数字在数组中出现的第一个和最后一个位置。
第一想法暴力。然后看要求时间复杂度O(logn),不说了,二分。不能二分就是不会。再看题目ascending order(ascend:上升),这就一有序的数组嘛,符合二分的条件。move hand。

知道用哪种方法,那怎么做呢?先讨论简单的情况,当nums[mid] ≠ target时,咱们直接选一边递归就可以了。麻烦的是当nums[mid] = target时。讨论一下

1.如果first和last下标都是-1,说明在此之前没有找到这个数。那么现在我们找到了就需要更新first和last为mid。

2.不然的话,我们只需要把first和mid,last与mid进行比较,然后替换就可以了。

注:其实开始写的很复杂,考虑了first = -1,last ≠ -1的情况,但分析发现,由于第一次找到mid时会同时更新两个的值,所以它们要么都是-1,要么都不是-1。

但是,这就完了吗?考虑nums为8,8,8;target=8的样例,当我们nums[mid]刚好为target时就不用再找找了吗?肯定不是啊,还要往两边去找,去更新两者。
有了大概的逻辑,代码实现就简单起来。直接上代码吧:

class Solution {
public:
    vector<int>ans;
    void binarySearch(vector<int>& nums, int target, int low, int high) {
        if (low > high) return; //记得跳出循环哦。
        int mid = (low + high) >> 1;
        if (nums[mid] == target) { // 中间值为target的情况哦。
            if (ans[0] == -1 && ans[1] == -1) ans[0] = ans[1] = mid;
            else {
                if (ans[0] > mid) ans[0] = mid;
                if (ans[1] < mid) ans[1] = mid;
            }
            /*千万别停止搜索,给我接着搜*/
            binarySearch(nums, target, low, mid - 1);
            binarySearch(nums, target, mid + 1, high);
        }
        /*中间不是就可以找一边了,中间是要找两边哦*/
        else if (nums[mid] > target) binarySearch(nums, target, low, mid - 1);
        else binarySearch(nums, target, mid + 1, high);
        return;
    }
    vector<int> searchRange(vector<int>& nums, int target) {
        ans = { -1,-1 };
        if (nums.size() == 0 || nums[0] > target || nums[nums.size() - 1] < target)
            return { -1,-1 };
        binarySearch(nums, target, 0, nums.size() - 1);
        return ans;
    }
};

这这这就完了吗?等一下,回顾一下与二分有关的函数。对了!不是有lower_bound()和upper_bound()函数吗?动手!

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> ans = { -1,-1 };
        if (nums.size() == 0 || nums[0] > target || nums[nums.size() - 1] < target
            || binary_search(nums.begin(), nums.end(), target) == 0)
            return { -1,-1 };
        ans[0] = lower_bound(nums.begin(), nums.end(), target) - nums.begin();
        ans[1] = upper_bound(nums.begin(), nums.end(), target) - nums.begin() - 1;
        return ans;
    }
};

这里简单说一下吧,low_bound(起始地址,结束地址,val)
作用:返回>=val的第一个地址。

upper_bound(起始地址,结束地址,val)
作用:返回>val的第一个地址。

那么这道题就搞定了,感谢你们看到这,也感谢我自己写到这。哈哈哈,表述不清的地方欢迎交流哦!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值