zoukankan      html  css  js  c++  java
  • LeetCode(34):搜索范围

    Medium!

    题目描述:

    给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

    你的算法时间复杂度必须是 O(log n) 级别。

    如果数组中不存在目标值,返回 [-1, -1]

    示例 1:

    输入: nums = [5,7,7,8,8,10], target = 8
    输出: [3,4]

    示例 2:

    输入: nums = [5,7,7,8,8,10], target = 6
    输出: [-1,-1]

    解题思路:

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

    C++解法一:

     1 class Solution {
     2 public:
     3     vector<int> searchRange(vector<int>& nums, int target) {
     4         int idx = search(nums, 0, nums.size() - 1, target);
     5         if (idx == -1) return {-1, -1};
     6         int left = idx, right = idx;
     7         while (left > 0 && nums[left - 1] == nums[idx]) --left;
     8         while (right < nums.size() - 1 && nums[right + 1] == nums[idx]) ++right;
     9         return {left, right};
    10     }
    11     int search(vector<int>& nums, int left, int right, int target) {
    12         if (left > right) return -1;
    13         int mid = left + (right - left) / 2;
    14         if (nums[mid] == target) return mid;
    15         else if (nums[mid] < target) return search(nums, mid + 1, right, target);
    16         else return search(nums, left, mid - 1, target);
    17     }
    18 };

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

    C++解法二:

     1 class Solution {
     2 public:
     3     vector<int> searchRange(vector<int>& nums, int target) {
     4         vector<int> res(2, -1);
     5         int left = 0, right = nums.size() - 1;
     6         while (left < right) {
     7             int mid = left + (right - left) / 2;
     8             if (nums[mid] < target) left = mid + 1;
     9             else right = mid;
    10         }
    11         if (nums[right] != target) return res;
    12         res[0] = right;
    13         right = nums.size();
    14         while (left < right) {
    15             int mid = left + (right - left) / 2;
    16             if (nums[mid] <= target) left = mid + 1;
    17             else right= mid;
    18         }
    19         res[1] = left - 1;
    20         return res;
    21     }
    22 };
  • 相关阅读:
    剑桥雅思写作高分范文ESSAY64
    剑桥雅思写作高分范文ESSAY63
    剑桥雅思写作高分范文ESSAY62
    剑桥雅思写作高分范文ESSAY61
    Python特点
    解释器
    python开发时总会碰到的问题
    python redis
    python连接数据库的方法
    数据库中的主键、外键、索引的区别
  • 原文地址:https://www.cnblogs.com/ariel-dreamland/p/9138119.html
Copyright © 2011-2022 走看看