美文网首页
Leecode[34] 在排序数组中查找元素的第一个和最后一个位

Leecode[34] 在排序数组中查找元素的第一个和最后一个位

作者: 饭板板 | 来源:发表于2020-10-01 15:40 被阅读0次

    题目

    给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
    你的算法时间复杂度必须是 O(log n) 级别。
    如果数组中不存在目标值,返回 [-1, -1]。

    算法分析

    • 时间复杂度必须是 O(log n) 级别,表示要用二分法。
    • 由于是升序数组,因此算出 mid。
    • 对于 nums[mid] > target 这种情况,查找区域收缩为 [start, mid-1]。
    • 对于 nums[mid] < target 这种情况,查找区域收缩为 [mid+1, start]。
    • 对于 nums[mid] = target 这种情况,查找区域收缩为 [start, mid-1]。
    public static int[] Method(int[] nums, int target)
    {
        Array.Sort(nums);
    
        var left = SearchLeftRange(nums, target);
    
        int right = -1;
        if (left != -1)
            right = SearchRightRange(nums, target);
    
        return new int[] { left, right };
    }
    
    private static int SearchLeftRange(int[] nums, int target)
    {
        int left = 0;
        int right = nums.Length - 1;
    
        while (left <= right)
        {
            int mid = left + (right - left) / 2; // 防止溢出、
            if (nums[mid] == target)
            {
                right = mid - 1;
            }
            else if (nums[mid] > target)
            {
                right = mid - 1;
            }
            else // nums[mid] < target
            {
                left = mid + 1;
            }
        }
    
        if (left != nums.Length && nums[left] == target)
        {
            return left;
        }
    
        return -1;
    }
    
    private static int SearchRightRange(int[] nums, int target)
    {
        int left = 0;
        int right = nums.Length - 1;
    
        while (left <= right)
        {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target)
            {
                left = mid + 1;
            }
            else if (nums[mid] < target)
            {
                left = mid + 1;
            }
            else // nums[mid] > target
            {
                right = mid - 1;
            }
        }
    
        return right;
    }
    
    

    注意:先搜索的边界函数(SearchLeftRange),如果 target 很大且不存在,需要判断 left 越界情况。同理,如果 target 很小且不存在,需要判断 right 越界情况,但 SearchLeftRange 已经可以知道 target 是否存在了。

    相关文章

      网友评论

          本文标题:Leecode[34] 在排序数组中查找元素的第一个和最后一个位

          本文链接:https://www.haomeiwen.com/subject/ohgmuktx.html