LeetCode 3159. 查询数字在数组中出现的次数 Java实现

3159. 查询数字在数组中出现的次数

题目来源

3159. 查询数字在数组中出现的次数

题目分析

给你一个整数数组 nums 和一个整数数组 queries

找出 queries 中每个查询的答案:查询中第 k 个出现的 x 的下标是 nums 中第 k 个。如果 xnums 中出现次数少于 k,那么答案是 -1

请你实现一个函数,返回查询的答案。

题目难度

  • 难度:中等

题目标签

  • 标签:数组、哈希表

题目限制

  • 1 <= nums.length, queries.length <= 10^5
  • 1 <= nums[i], queries[i] <= 10^6

解题思路

思路:数组记录法

  1. 问题定义
    • 对于每个查询 queries[i],需要找到数组 nums 中第 queries[i] 个出现的 x 的下标。
  2. 核心算法
    • 遍历数组 nums,记录所有等于 x 的元素的下标。
    • 使用一个列表 pos 来存储这些下标。
    • 对于每个查询,检查 queries[i] 是否大于 pos 的长度,如果是,则返回 -1;否则返回 pos 中第 queries[i] - 1 个元素。
  3. 关键步骤
    • 初始化一个列表 pos
    • 遍历 nums,将等于 x 的元素的下标添加到 pos 中。
    • 遍历 queries,对于每个查询,返回对应的下标或 -1

核心算法步骤

  1. 初始化列表
    • 创建一个 ArrayList<Integer> 类型的列表 pos,用于存储等于 x 的元素的下标。
  2. 记录下标
    • 遍历 nums,当 nums[i] == x 时,将下标 i 添加到 pos 中。
  3. 处理查询
    • 遍历 queries,对于每个查询 queries[i],检查其是否大于 pos 的长度,如果是,则答案为 -1;否则答案为 pos.get(queries[i] - 1)
  4. 返回结果
    • 返回一个整数数组 ans,其中包含所有查询的答案。

代码实现

以下是数组记录法的 Java 代码实现:

public int[] occurrencesOfElement(int[] nums, int[] queries, int x) {
    ArrayList<Integer> pos = new ArrayList<>();
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] == x) {
            pos.add(i);
        }
    }
    int[] ans = new int[queries.length];
    for (int i = 0; i < queries.length; i++) {
        ans[i] = pos.size() < queries[i] ? -1 : pos.get(queries[i] - 1);
    }
    return ans;
}

代码解读

  • 记录下标:通过遍历 nums,将所有等于 x 的元素的下标添加到列表 pos 中。
  • 处理查询:对于每个查询 queries[i],检查其在 pos 中的位置,并返回相应的下标或 -1

性能分析

  • 时间复杂度O(n + q),其中 n 是数组 nums 的长度,q 是数组 queries 的长度。遍历 nums 的时间复杂度是 O(n),处理每个查询的时间复杂度是 O(1)
  • 空间复杂度O(n),用于存储等于 x 的元素的下标。

测试用例

你可以使用以下测试用例来验证代码的正确性:

public static void main(String[] args) {
    int[] nums = {1, 2, 3, 4, 2, 2};
    int[] queries = {1, 2, 3};
    int x = 2;
    int[] ans = occurrencesOfElement(nums, queries, x);
    System.out.println(Arrays.toString(ans)); // 输出: [1, 4, -1]
}

扩展讨论

有没有其他方法?

除了上述方法,我们还可以考虑以下方法:

双指针法

如果我们知道 xnums 中出现的次数,我们可以使用双指针来找到第 k 个出现的 x 的下标。但是这种方法需要先遍历一次 nums 来统计 x 的出现次数,然后再进行第二次遍历来找到第 kx 的下标。

二分查找法

如果我们预先处理 nums,将所有等于 x 的元素的下标存储在一个数组中,那么对于每个查询,我们可以使用二分查找来快速找到第 k 个出现的 x 的下标。这种方法在查询数量非常多时可能更高效。

总结

本题的核心在于如何有效地记录和查询特定元素在数组中的出现位置。通过使用列表来记录所有等于 x 的元素的下标,我们可以轻松地处理查询。这种方法简单直观,且在大多数情况下都能提供不错的性能。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值