摘要:题目要求即在一个有序排列的数组中,找到目标值所在的起始下标和结束下标。这样一定可以找到目标值的初始下标同理,结合情况和情况,当中间值大于目标值,则将右指针左移至中间,否则将左指针右移至中间,这样一定可以找到目标值的结束下标。
题目要求
Given an array of integers 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]. For example, Given [5, 7, 7, 8, 8, 10] and target value 8, return [3, 4].
即 在一个有序排列的数组中,找到目标值所在的起始下标和结束下标。如果该目标值不在数组中,则返回[-1,-1]
题目中有一个特殊要求是时间复杂度为O(logn),也就是在暗示我们,不能只是单纯的按照顺序遍历数组,要尽量减去无效遍历。所以这题的核心思路为二分法遍历。
最初的思路是使用二分法找到目标值的其中一个下标,再根据该下标左右遍历得出初始下标和结束下标。
public int[] searchRange(int[] nums, int target) { int[] result = new int[]{-1, -1}; int left = 0; int right = nums.length-1; while(left<=right){ int mid = (left + right)/2; if(nums[mid]==target){ while(mid>=left && nums[mid]==target){ mid--; } result[0] = mid+1; mid = (left + right)/2; while(mid<=right && nums[mid]==target){ mid++; } result[1] = mid - 1; break; }else if (nums[mid] > target){ right = mid-1; }else{ left = mid+1; } } return result; }思路二:二分法分别运用
假设我们目前有左指针,右指针,并判断中间值和目标值之间的关系,那么一共有三种关系情况
中间值小于目标值,则目标值只可能在右子数组
中间值大于目标值,则目标值只可能在左子数组
中间值等于目标值,则目标值在左右子数组都可能存在
结合情况1和情况3,当中间值小于目标值,则将左指针右移至中间,否则将右指针左移至中间。这样一定可以找到目标值的初始下标
同理,结合情况2和情况3,当中间值大于目标值,则将右指针左移至中间,否则将左指针右移至中间,这样一定可以找到目标值的结束下标。
public int[] searchRange2(int[] nums, int target) { int[] range = new int[]{nums.length, -1}; searchRange2(nums, target, 0, nums.length, range); if(range[0]>range[1]) range[0]=-1; return range; } public void searchRange2(int[] nums, int target, int left, int right, int[] range){ if(left>right) return; int mid = ( left + right ) / 2; if(nums[mid] == target){ if(mid < range[0]){ range[0] = mid; searchRange2(nums, target,left, mid-1, range); } if(mid > range[1]){ range[1] = mid; searchRange2(nums, target, mid+1, right, range); } }else if (nums[mid]这种思路更清晰的代码表示如下
public int[] searchRange3(int[] nums, int target) { int[] result = new int[2]; result[0] = findFirst(nums, target); result[1] = findLast(nums, target); return result; } private int findFirst(int[] nums, int target){ int idx = -1; int start = 0; int end = nums.length - 1; while(start <= end){ int mid = (start + end) / 2; if(nums[mid] >= target){ end = mid - 1; }else{ start = mid + 1; } if(nums[mid] == target) idx = mid; } return idx; } private int findLast(int[] nums, int target){ int idx = -1; int start = 0; int end = nums.length - 1; while(start <= end){ int mid = (start + end) / 2; if(nums[mid] <= target){ start = mid + 1; }else{ end = mid - 1; } if(nums[mid] == target) idx = mid; } return idx; }
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/69966.html
摘要:我们要找出这个目标数字在数组中的存在区间,并以数组形式返回这个区间。要求题目必须在输入数组和目标值返回想法我们需要分别找出最左边的这个元素的位置和最右边的这个元素的位置。由于对于时间的要求,我们在进行查找的时候要采取二分查找。 题目详情 Given an array of integers sorted in ascending order, find the starting and...
摘要:二分搜索复杂度时间空间思路其实就是执行两次二分搜索,一次专门找左边边界,一次找右边边界。如果找右边边界,则要判断右边一位的数是否相同。 Search for a Range Given a sorted array of integers, find the starting and ending position of a given target value. Your algo...
摘要:前言从开始写相关的博客到现在也蛮多篇了。而且当时也没有按顺序写现在翻起来觉得蛮乱的。可能大家看着也非常不方便。所以在这里做个索引嘻嘻。顺序整理更新更新更新更新更新更新更新更新更新更新更新更新更新更新更新更新 前言 从开始写leetcode相关的博客到现在也蛮多篇了。而且当时也没有按顺序写~现在翻起来觉得蛮乱的。可能大家看着也非常不方便。所以在这里做个索引嘻嘻。 顺序整理 1~50 1...
摘要:首先,建立二元结果数组,起点,终点。二分法求左边界当中点小于,移向中点,否则移向中点先判断起点,再判断终点是否等于,如果是,赋值给。 Problem Given a sorted array of n integers, find the starting and ending position of a given target value. If the target is not...
摘要:如果目标值不存在于数组中,返回它将会被按顺序插入的位置。因此需要关注这些测试用例,在单机上逐个测试成功后再提交。因为题目中只要求返回索引,并不要求插到数组中,所以应该说又简化了一些,是一道简单题目。争取在下一篇给出优化解法。 「 Leetcode刷题 」系列,仅为刷题过程中对于算法和编程的思考与记录,如果对你有帮助欢迎点赞收藏。博主也在探索刷题过程中,记录的一些知识点可能很小白,因此主...
阅读 3891·2021-11-11 10:58
阅读 3242·2021-09-26 09:46
阅读 1878·2019-08-30 15:55
阅读 948·2019-08-30 13:52
阅读 1922·2019-08-29 13:11
阅读 2984·2019-08-29 11:27
阅读 1486·2019-08-26 18:18
阅读 2557·2019-08-23 14:17