• Leetcode: Find First and Last Position of Element in Sorted Array


    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].

    Analysis: 这道题是二分查找Search Insert Position的变体,思路并不复杂,就是先用二分查找找到其中一个target,然后再往左右找到target的边缘。找边缘的方法跟二分查找仍然是一样的,只是相等的情况依然要往左找(找左边缘)或往右找(找右边缘)。这样下来总共进行了三次二分查找,所以算法的时间复杂度仍是O(logn),空间复杂度是O(1)。

    Notice: 对停止的边界条件极不熟悉,需要总结,参见Binary Search的Summary

    本题的精髓和难点在于寻找左右边沿,方法是Binary Search的变体,只不过这次是要左右相遇。以找左边缘为例,while循环里要么A[m] < target, l 跳到m+1, 要么A[m]==target, r 跳到m-1, 直到l > r为止,这时候l所在的位置就是要求的左边缘。而如果是找右边缘,l > r之后,r所在位置就是要求的右边缘。l和r所停的位置正好是目标数的后面和前面。

    找左边沿可以认为是在找一个比target略小的目标数(因为等于target的时候移动的是右边缘),这个目标数在A中不存在,所以当循环结束时候,l, r分别处在目标数的后面和前面。如果我们找的是左边缘,那么这个左边缘应该是在目标数右边,所以就是l所处的位置

    整体如果想用iterative的方法来写:

    两次binary search, 一次找左边缘,一次找右边缘, be carefule of line 12, r有可能<0

     1 public class Solution {
     2     public int[] searchRange(int[] nums, int target) {
     3         int[] res = new int[]{-1, -1};
     4         if (nums==null || nums.length==0) return res;
     5         int l=0, r=nums.length-1;
     6         int m = l + (r-l)/2;
     7         while (l <= r) { // find right edge
     8             m = l + (r-l)/2;
     9             if (nums[m] <= target) l = m + 1;
    10             else r = m - 1;
    11         }
    12         if (r<0 || nums[r] != target) return res;
    13         else res[1] = r;
    14         
    15         l = 0;
    16         //no need to set r = nums.length - 1, because r is already at right place
    17         while (l <= r) {
    18             m = l + (r-l)/2;
    19             if (nums[m] < target) l = m + 1;
    20             else r = m - 1;
    21         }
    22         res[0] = l;
    23         return res;
    24     }
    25 }
  • 相关阅读:
    pycharm 安装第三方库,出现错误: error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visual studio.com/visual-cpp-build-tools
    c# 开发常用小方法
    [LeetCode]28. 实现 strStr()
    [LeetCode]27. 移除元素
    [LeetCode]21. 合并两个有序链表
    [LeetCode]20. 有效的括号
    [LeetCode]14. 最长公共前缀
    [LeetCode]13. 罗马数字转整数
    [LeetCode]9. 回文数
    [LeetCode]2. 两数相加
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/3811193.html
Copyright © 2020-2023  润新知