当前位置: 首页 > article >正文

力扣 2080. 区间内查询数字的频率 离散化 二分 开区间 左闭右开区间 lowerBound

Problem: 2080. 区间内查询数字的频率
在这里插入图片描述

在这里插入图片描述

👨‍🏫 参考题解
👨‍🏫 参考视频

在这里插入图片描述

🍚 左闭右开二分

class RangeFreqQuery {
    private final Map<Integer, List<Integer>> pos = new HashMap<>();

    public RangeFreqQuery(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
             //初始化时,存放每个元素出现的下标位置,这个list本身已经是有序的,因为我们是按照下标开始存进去的,存的也是下标
            pos.computeIfAbsent(arr[i], k -> new ArrayList<>()).add(i);
        }
    }

    public int query(int left, int right, int value) {
        List<Integer> a = pos.get(value);
        if (a == null) {
            return 0;
        }
        return lowerBound(a, right + 1) - lowerBound(a, left);
    }

    // 开区间写法
    // 请看 https://www.bilibili.com/video/BV1AP41137w7/
    // 找到第一个 >= target 的下标,没有则返回数组长度
    private int lowerBound(List<Integer> a, int target) {
        // 左闭右开区间 [left, right)
        int left = 0;
        int right = a.size();
        while (left < right) { // 区间不为空
            int mid = (left + right) >>> 1;
            if (a.get(mid) < target) {
                left = mid + 1; // 范围缩小到 [mid + 1, right)
            } else {
                right = mid; // 范围缩小到 [left, mid)
            }
        }
        return left; // right 是最小的满足 a[right] >= target 的下标
    }
}

🍚 开区间二分

class RangeFreqQuery {
    private final Map<Integer, List<Integer>> pos = new HashMap<>();

    public RangeFreqQuery(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
             //初始化时,存放每个元素出现的下标位置,这个list本身已经是有序的,因为我们是按照下标开始存进去的,存的也是下标
            pos.computeIfAbsent(arr[i], k -> new ArrayList<>()).add(i);
        }
    }

    public int query(int left, int right, int value) {
        List<Integer> a = pos.get(value);
        if (a == null) {
            return 0;
        }
        return lowerBound(a, right + 1) - lowerBound(a, left);
    }

    // 开区间写法
    // 请看 https://www.bilibili.com/video/BV1AP41137w7/
    private int lowerBound(List<Integer> a, int target) {
        // 开区间 (left, right)
        int left = -1;
        int right = a.size();
        while (left + 1 < right) { // 区间不为空
            // 循环不变量:
            // a[left] < target
            // a[right] >= target
            int mid = (left + right) >>> 1;
            if (a.get(mid) < target) {
                left = mid; // 范围缩小到 (mid, right)
            } else {
                right = mid; // 范围缩小到 (left, mid)
            }
        }
        return left; // right 是最小的满足 a[right] >= target 的下标
    }
}

http://www.kler.cn/a/459587.html

相关文章:

  • GXUOJ-算法-补题:22级《算法设计与分析》第一次课堂练习
  • springboot实战(19)(条件分页查询、PageHelper、MYBATIS动态SQL、mapper映射配置文件、自定义类封装分页查询数据集)
  • Unity Canvas中显示粒子特效
  • Django-Easy-Audit 实战:轻松实现数据审计
  • Maple软件的安装和使用
  • ORA-01187 it failed verification tests 增加tempfile
  • Linux下编译 libwebsockets简介和使用示例
  • GPUStack v0.4.1 单节点与多节点安装与部署指南 Docker PowerShell
  • 2. FPGA基础了解--全局网络
  • 18.springcloud_openfeign之扩展组件二
  • Prometheus学习笔记
  • 【鸿蒙NEXT】鸿蒙里面类似iOS的Keychain——关键资产(@ohos.security.asset)实现设备唯一标识
  • ES6模块化:JavaScript中的导入与导出详解
  • TypeScript一些新概念
  • leetcode 9.回文数(整数不转成字符串)
  • GDPU Vue前端框架开发 跨年大礼包
  • Go-知识 模板
  • LLM常见面试题(31-35题)--深度学习基础概念
  • 计算机网络-L2TP Over IPSec基础实验
  • 【运维】部署Gitea
  • 目标检测入门指南:从原理到实践
  • Redis 安装部署[主从、哨兵、集群](windows版)
  • 爆改RagFlow
  • 【UE5】UnrealEngine源码构建3:启动UE5工程
  • 二、AI知识(神经网络)
  • 210.xxl-job定时任务:架构,可视化,GLUE模式,负载均衡,分片