zoukankan      html  css  js  c++  java
  • [LeetCode] 34. Find First and Last Position of Elements in Sorted Array(在有序数组中寻找某个元素第一次和最后一次出现的位置)

    Description

    Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value.
    给定一个升序排序整数数组 nums,找给定值 target 的第一次和最后一次出现的位置。

    If target is not found in the array, return [-1, -1].
    如果 target 未找到,返回 [-1, -1]

    Follow up

    Could you write an algorithm with O(log n) runtime complexity?
    你能在 O(log n) 时间复杂度下完成吗?

    Examples

    Example 1

    Input: nums = [5,7,7,8,8,10], target = 8
    Output: [3,4]
    

    Example 2

    Input: nums = [5,7,7,8,8,10], target = 6
    Output: [-1,-1]
    

    Example 3

    Input: nums = [], target = 0
    Output: [-1,-1]
    

    Constraints

    • 0 <= nums.length <= 1e5
    • -1e9 <= nums[i] <= 1e9
    • nums is a non-decreasing array.
    • -1e9 <= target <= 1e9

    Solution

    这题实际上是两个子问题的缝合:寻找一个数在数组里的左边界和右边界。这是二分查找的变式,具体解法可以参考这篇博客:详解二分查找算法 - murphy_gb - 博客园 (cnblogs.com),代码如下:

    class Solution {
        fun searchRange(nums: IntArray, target: Int): IntArray {
            return intArrayOf(leftBound(nums, target), rightBound(nums, target))
        }
    
        private fun leftBound(nums: IntArray, target: Int): Int {
            if (nums.isEmpty()) {
                return -1
            }
            var left = 0
            var right = nums.size
            while (left < right) {
                val mid = left + (right - left) / 2
                if (nums[mid] < target) {
                    left = mid + 1
                } else {
                    right = mid
                }
            }
            if (left == nums.size) {
                return -1
            }
            return if (nums[left] == target) {
                left
            } else {
                -1
            }
        }
    
        private fun rightBound(nums: IntArray, target: Int): Int {
            if (nums.isEmpty()) {
                return -1
            }
            var left = 0
            var right = nums.size
            while (left < right) {
                val mid = left + (right - left) / 2
                if (nums[mid] <= target) {
                    left = mid + 1
                } else {
                    right = mid
                }
            }
            if (left == 0) {
                return -1
            }
            return if (nums[left - 1] == target) {
                left - 1
            } else {
                -1
            }
        }
    }
    
  • 相关阅读:
    异常、中断、陷阱
    BigDecimal
    事务
    jsp的九大内置对象
    timer和ScheduledThreadPoolExecutor
    关于Python的导入覆盖解决办法
    RTTI
    Golang不会自动把slice转换成interface{}类型的slice
    Python中下划线的5种含义
    Python如何合并两个字典
  • 原文地址:https://www.cnblogs.com/zhongju/p/14088494.html
Copyright © 2011-2022 走看看