剑指Offer03.数组中重复的数字 c++实现
写在前面,小白从零刷题,在解答会写出思路,正确答案,以及所有使用到的语法和知识点
1. 使用集合
- 思路就是利用集合不能有重复数字的这个特性,把数组中的元素依次送入集合当中,判断一下这个元素是否被送入,如果已经被送入,那么返回该值,这样得到的是第一个重复的元素
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
set<int> res;
for(auto i:nums)//利用i遍历容器中的每一个值,nums为容器,i无法影响容器内的值
{
if(res.count(i) == 1)//这里吐槽下就不能换个集合的名字吗非得和count函数一致
{
return i;
}
else
{
count.insert(i);//集合的插入函数
}
}
return 0;
}
};
2不看答案做
class Solution {
public:
int findRepeatNumber(vector<int>& nums)
{
set<int>res;
for(auto i:nums)//此处就是写nums,而不是写nums的长度
{
if(res.count(i)==1)
{
return i;
}
else
{
res.insert(i);
}
}
return -1;
}
};
2.原地交换法
1.其实这个方法的思路不是特别懂,但是实在理解不了了,基本思路就是要先排序,因为题目可以分析出如果顺序正确那么下标和下标对应的数组元素是否一致的,如果不一致,判断是否有nums[i] == nums[nums[i]],如果不重复那么交换这两个元素,接着下一个。单证不太理解这里的方法之后希望可以搞懂吧
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
//遍历数组,将i与nums[i]对应起来
for(int i = 0; i < nums.size(); ++i) {
//如果当前值的下标不等于当前值,如 1 != nums[1]:2
while(i != nums[i]) {
//如果nums[1]:2 == nums[2],找到相同数字,但下标不同,则说明出现重复数字
if(nums[i] == nums[nums[i]])
//返回该数字
return nums[i];
//若不相等
else
//则交换nums[i]和nums[nums[i]],一直循环交换
swap(nums[i], nums[nums[i]]);
}
}
return 0;
}
};
- 不看答案做
class Solution {
public:
int findRepeatNumber(vector<int>& nums){
for(int i;i<nums.size();i++)//牢记定义一个变量一定要初始化,刚刚未初始化,就出错了
{
while(i!=nums[i])
{
if(nums[i]==nums[nums[i]])
{
return nums[i];
}
else
{
swap(nums[i],nums[nums[i]]);
}
}
}
return 0;
}
};
知识点及反思
- set c++primer 11.1
- C++set用法总结
- set自动忽略重复的元素,且从小到大排列,
- c++中的for(auto a:b)用法
- 范围for语句 c++primer 5.4.3
- 最开始可以使用无序的集合,这样速度会快,原因应该是不需要进行排序这一项操作