9、数组中重复的数
大约 4 分钟数据结构算法算法基地面试数组哈希表原地算法剑指Offer刷题程序厨校招社招
题目描述
剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0 ~ n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3
HashSet
解析
这种题目或许一下就让人想到 HashSet,题目描述很清楚就是让我们找到数组中重复的元素,那我们第一下想到的就是 HashSet,我们遍历数组,如果发现 set 含有该元素则返回,不含有则存入哈希表,题目代码也很简单
题目代码
Java:
class Solution {
public int findRepeatNumber(int[] nums) {
// HashSet
HashSet<Integer> set = new HashSet<Integer>();
for (int x : nums) {
//发现某元素存在,返回
if (set.contains(x)) {
return x;
}
//存入哈希表
set.add(x);
}
return -1;
}
}
C++:
#include <vector>
#include <unordered_set> // 包含哈希集合的头文件
using namespace std; // 引入标准命名空间,简化代码书写
class Solution {
public:
int findRepeatDocument(vector<int>& nums) {
unordered_set<int> numSet; // 定义哈希集合,用于存储已遍历的数字
for (const int x : nums) {
// 检查当前数字是否已在集合中:
// unordered_set的find方法返回迭代器,若找到则指向该元素,否则指向end()
if (numSet.find(x) != numSet.end()) {
return x; // 找到重复数字,直接返回
}
numSet.insert(x); // 若未重复,将当前数字插入集合
}
return -1; // 遍历结束未发现重复(题目通常保证有重复,此处按原逻辑保留)
}
};
原地置换
解析
这一种方法也是我们经常用到的,主要用于重复出现的数,缺失的数等题目中,下面我们看一下这个原地置换法,原地置换的大体思路就是将我们指针对应的元素放到属于他的位置(索引对应的地方)。我们可以这样理解,每个人都有自己的位置,我们需要和别人调换回到属于自己的位置,调换之后,如果发现我们的位置上有人了,则返回。大致意思了解了,下面看代码的执行过程。通过视频一下就可以搞懂啦。

题目代码
Java Code:
class Solution {
public int findRepeatNumber(int[] nums) {
if (nums.length == 0) {
return -1;
}
for (int i = 0; i < nums.length; ++i) {
while (nums[i] != i) {
//发现重复元素
if (nums[i] == nums[nums[i]]) {
return nums[i];
}
//置换,将指针下的元素换到属于他的索引处
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -1;
}
}
C++ Code:
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
if(nums.empty()) return 0;
int n = nums.size();
for(int i = 0; i < n; ++i){
while(nums[i] != i){
if(nums[i] == nums[nums[i]]) return nums[i];
swap(nums[i], nums[nums[i]]);
}
}
return -1;
}
};





