Problem: 2053. 数组中第 K 个独一无二的字符串
文章目录
- [1. 整体思路](#1. 整体思路)
- [2. 完整代码](#2. 完整代码)
- [3. 时空复杂度](#3. 时空复杂度)
-
-
- [时间复杂度: O ( N ) O(N) O(N)](#时间复杂度: O ( N ) O(N) O(N))
- [空间复杂度: O ( N ) O(N) O(N)](#空间复杂度: O ( N ) O(N) O(N))
-
1. 整体思路
核心问题
我们需要找到数组中第 k 个只出现一次的字符串。
- 独一无二 (Distinct):该字符串在数组中出现的次数必须恰好为 1。
- 顺序 :按照字符串在原数组中出现的顺序来数第
k个。
算法逻辑
-
第一遍遍历(计数):
- 遍历整个数组
arr。 - 使用一个哈希表 (
HashMap) 来统计每个字符串出现的频次。 key: 字符串,value: 出现次数。
- 遍历整个数组
-
第二遍遍历(查找):
- 再次按顺序遍历数组
arr。 - 对于每个字符串
s,检查它在哈希表中的计数是否为 1。 - 如果是 1(说明是独一无二的),则将计数器
k减 1。 - 当
k减到 0 时,说明当前这个s就是我们要找的目标,直接返回。
- 再次按顺序遍历数组
-
兜底返回:
- 如果遍历完整个数组,
k依然大于 0,说明独一无二的字符串不足k个,返回空字符串""。
- 如果遍历完整个数组,
2. 完整代码
java
import java.util.HashMap;
class Solution {
public String kthDistinct(String[] arr, int k) {
// 创建哈希表,用于存储每个字符串的出现次数
HashMap<String, Integer> count = new HashMap<>();
// 第一遍遍历:统计频次
for (String s : arr) {
// merge 方法是 Java 8 引入的简化 Map 更新操作的方法
// 如果 key 不存在,存入 value (这里是 1)
// 如果 key 存在,执行 remappingFunction (这里是 Integer::sum,即旧值+1)
count.merge(s, 1, Integer::sum);
// 等价于传统写法:
// count.put(s, count.getOrDefault(s, 0) + 1);
}
// 第二遍遍历:按原数组顺序寻找第 k 个独一无二的字符串
for (String s : arr) {
// 检查当前字符串的出现次数是否为 1
if (count.get(s) == 1) {
// 找到了一个独一无二的字符串,k 减 1
k--;
// 如果 k 变成了 0,说明这就是第 k 个,直接返回
if (k == 0) {
return s;
}
}
}
// 如果遍历结束仍未找到第 k 个,返回空字符串
return "";
}
}
3. 时空复杂度
假设数组 arr 的长度为 N N N。
时间复杂度: O ( N ) O(N) O(N)
- 第一遍循环 :遍历 N N N 个字符串,HashMap 的插入/更新操作平均为 O ( 1 ) O(1) O(1)。总耗时 O ( N ) O(N) O(N)。
- 第二遍循环 :遍历 N N N 个字符串,HashMap 的查找操作平均为 O ( 1 ) O(1) O(1)。总耗时 O ( N ) O(N) O(N)。
- 总计 : O ( N ) + O ( N ) = O ( N ) O(N) + O(N) = O(N) O(N)+O(N)=O(N)。
空间复杂度: O ( N ) O(N) O(N)
- 哈希表开销 :在最坏情况下(所有字符串都不同),HashMap 需要存储 N N N 个键值对。
- 结论 : O ( N ) O(N) O(N)。