博客
关于我
【LeetCode(Java) - 34】在排序数组中查找元素的第一个和最后一个位置
阅读量:57 次
发布时间:2019-02-25

本文共 1525 字,大约阅读时间需要 5 分钟。

解决数组中目标值范围问题

问题描述

我们需要找到一个数组 nums 中的目标值 target 的范围,即找到 target 的第一个和最后一个出现位置。如果 target 不在数组中,返回一个空数组。


解题思路

我们可以定义一个辅助方法 extremeInsertionIndex,用于查找目标值 target 在数组中的开始位置或结束位置。这个方法有两个参数:

  • left 参数为 true 时,返回目标值的开始位置;
  • false 时返回目标值的结束位置。

查找开始位置的逻辑

  • 初始化边界:

    • 左边界 lo 设为 0;
    • 右边界 hi 设为数组长度。
  • 使用二分查找法:

    • 计算中间值 mid
    • 如果 nums[mid] 大于目标值,说明目标值在左边界,更新右边界 himid
    • 如果 nums[mid] 等于目标值,可能 mid 就是开始位置,更新右边界 himid
    • 当边界闭合时,返回左边界 lo
  • 查找结束位置的逻辑

  • 同样初始化边界 lohi
    • 如果 nums[mid] 大于目标值,更新右边界 himid
    • 如果 nums[mid] 等于目标值,更新左边界 lomid + 1
    • 返回右边界 hi 并减 1。

  • 解题代码

    class Solution {    private int extremeInsertionIndex(int[] nums, int target, boolean left) {        int lo = 0, hi = nums.length;        while (lo < hi) {            int mid = lo + (hi - lo) / 2;            if (nums[mid] > target || (left && target == nums[mid])) {                hi = mid;            } else {                lo = mid + 1;            }        }        return lo;    }    public int[] searchRange(int[] nums, int target) {        int[] result = {-1, -1};        int leftIdx = extremeInsertionIndex(nums, target, true);        if (leftIdx == nums.length || nums[leftIdx] != target) {            return result;        }        result[0] = leftIdx;        result[1] = extremeInsertionIndex(nums, target, false) - 1;        return result;    }}

    代码解释

  • 辅助方法 extremeInsertionIndex

    • 根据 left 参数判断查找方向;
    • 使用二分查找法缩小查找范围,找到目标值的边界位置。
  • 主方法 searchRange

    • 初始化结果数组为 -1
    • 调用 extremeInsertionIndex查找左边界;
    • 检查左边界是否有效,若无效则返回空数组;
    • 再次调用查找右边界,并调整为 rightEnd - 1
    • 返回目标值的范围。
  • 通过这种方法,我们可以高效地找到目标值在数组中的范围,时间复杂度为 O(log n)。

    转载地址:http://mwq.baihongyu.com/

    你可能感兴趣的文章
    Netty工作笔记0007---NIO的三大核心组件关系
    查看>>
    Netty工作笔记0011---Channel应用案例2
    查看>>
    Netty工作笔记0013---Channel应用案例4Copy图片
    查看>>
    Netty工作笔记0014---Buffer类型化和只读
    查看>>
    Netty工作笔记0020---Selectionkey在NIO体系
    查看>>
    Vue踩坑笔记 - 关于vue静态资源引入的问题
    查看>>
    Netty工作笔记0025---SocketChannel API
    查看>>
    Netty工作笔记0027---NIO 网络编程应用--群聊系统2--服务器编写2
    查看>>
    Netty工作笔记0050---Netty核心模块1
    查看>>
    Netty工作笔记0057---Netty群聊系统服务端
    查看>>
    Netty工作笔记0060---Tcp长连接和短连接_Http长连接和短连接_UDP长连接和短连接
    查看>>
    Netty工作笔记0063---WebSocket长连接开发2
    查看>>
    Netty工作笔记0070---Protobuf使用案例Codec使用
    查看>>
    Netty工作笔记0077---handler链调用机制实例4
    查看>>
    Netty工作笔记0084---通过自定义协议解决粘包拆包问题2
    查看>>
    Netty工作笔记0085---TCP粘包拆包内容梳理
    查看>>
    Netty常用组件一
    查看>>
    Netty常见组件二
    查看>>
    netty底层源码探究:启动流程;EventLoop中的selector、线程、任务队列;监听处理accept、read事件流程;
    查看>>
    Netty心跳检测机制
    查看>>