面试中查找数组重复元素应优先用array_count_values()统计频次再过滤,存在性判断用count()与array_unique()长度对比,禁用内置函数时用手动哈希表遍历,复杂类型需序列化或哈希处理。

用 array_count_values 统计频次是最直接的方法
面试中遇到“查找数组中重复元素”,第一反应不应该是手写循环,而是调用 PHP 原生函数。`array_count_values()` 能一次性统计每个值出现的次数,返回关联数组(值 → 出现次数),之后过滤出次数大于 1 的键即可。
示例代码:
$arr = [1, 2, 3, 2, 4, 3, 5]; $counts = array_count_values($arr); $duplicates = array_keys(array_filter($counts, fn($n) => $n > 1)); // 结果:[2, 3]
注意:该函数仅支持字符串和整数键值,若数组含浮点数、null、数组或对象,会触发警告或结果不可靠。面试时可主动说明这个限制,并视情况补充处理逻辑。
去重对比法适合判断“是否存在重复”
如果题目只要求返回 true/false(例如“判断数组是否有重复元素”),无需列出哪些重复,最高效的方式是比对原数组长度与去重后长度:
立即学习“PHP免费学习笔记(深入)”;
- `count($arr) !== count(array_unique($arr))` → 有重复
- 时间复杂度接近 O(n),内部基于哈希表,比双重循环 O(n²) 快得多
- `array_unique()` 默认保留首次出现的键,且会重排数字键,但只做存在性判断时不影响结果
手动遍历 + 哈希表记录适合考察底层思路
当面试官明确要求“不用内置函数”或想看你的循环与数据结构运用能力,推荐用一个临时数组(模拟哈希表)边遍历边记录已见元素:
function findDuplicates($arr) {
$seen = [];
$duplicates = [];
foreach ($arr as $val) {
if (isset($seen[$val])) {
if (!in_array($val, $duplicates)) {
$duplicates[] = $val;
}
} else {
$seen[$val] = true;
}
}
return $duplicates;
}
关键细节:
- 用 `isset($seen[$val])` 判断是否存在,比 `array_key_exists` 更快,也避免未定义索引警告
- 内层 `!in_array(...)` 是为了去重结果本身(同一个重复值只加一次),也可改用 `$duplicates = array_unique($duplicates)` 放在最后
- 注意 PHP 中 `==` 和 `===` 的区别:若需严格类型匹配(如 1 和 '1' 视为不同),应确保键名类型一致,或改用 `spl_object_hash()` 处理对象
处理多维数组或复杂类型要转换键名
原生函数对嵌套数组无效。若题目给的是二维数组(如 `[ ['id'=>1], ['id'=>2], ['id'=>1] ]`),需先序列化或生成唯一标识符作为键:
- `$key = md5(serialize($item))` 或更轻量的 `json_encode($item, JSON_UNESCAPED_UNICODE)`
- 再用类似哈希表方式统计,避免 `array_count_values` 报错
- 对象同理,可用 `spl_object_hash($obj)` 获取唯一句柄,但要注意生命周期——同一对象多次调用返回相同 hash,不同对象即使属性相同也不同
不复杂但容易忽略。











