欢迎光临
我们一直在努力

千问 LeetCode 442. 数组中重复的数据 Java实现

这道题是经典的数组原地哈希问题,非常适合用来练习 O(1) 空间复杂度的技巧。

题目简述

给定一个长度为 n 的整数数组 nums,其中所有整数都在范围 [1, n] 内,且每个整数出现 一次或两次。请找出所有出现 两次 的整数。

要求:时间复杂度 O(n),空间复杂度 O(1)(不包括输出数组)。

核心思路

利用数组下标作为哈希表。由于数字范围是 [1, n],我们可以将数字 x 映射到下标 x – 1。遍历数组时,将对应下标的元素取反作为“已访问”标记。如果某个下标的元素已经是负数,说明对应的数字之前已经出现过,即为重复数据。

Java 实现

import java.util.ArrayList;
import java.util.List;

class Solution {
public List findDuplicates(int[] nums) {
List result = new ArrayList<>();

for (int i = 0; i < nums.length; i++) {
// 取绝对值,因为之前的操作可能已经将其变为负数
int index = Math.abs(nums[i]) – 1;

// 如果对应位置的数已经是负数,说明之前访问过,即找到了重复
if (nums[index] < 0) {
result.add(Math.abs(nums[i]));
} else {
// 否则,将其标记为已访问(取反)
nums[index] = -nums[index];
}
}

return result;
}

}

复杂度分析

  • 时间复杂度:O(n),只需遍历数组一次。
  • 空间复杂度:O(1),除输出数组外没有使用额外空间。

面试延伸

如果面试官追问其他解法,可以补充:

  • 排序法:排序后相邻元素比较,时间 O(n log n),空间 O(1)。
  • HashSet:遍历时判断是否已存在,时间 O(n),空间 O(n)。
  • 交换归位法:将每个数字放到其对应的下标位置,如果目标位置已有正确数字则说明重复。

原地取反法是这类“数字范围在 [1, n]”题目的通用技巧,掌握后可以快速应对类似变体。

需要我接着为你讲解同系列高频面试题 LeetCode 287. 寻找重复数的 Java 实现吗?
在这里插入图片描述

赞(0)
未经允许不得转载:171主机测评 » 千问 LeetCode 442. 数组中重复的数据 Java实现
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址