第一个出现的非重复数字
First occurring non-repeating number
假设你有一个数字向量,例如:
0,4,2,3,1,0,6,4查找此列表中第一个不重复的数字。因此,为了示例起见,答案是2。假设:
- 您可以修改提供的矢量
- 如果找不到任何内容,则返回 -1
- 提供的数字介于 0 - 10,000 之间
我提供了两个我想到的答案,我认为称为ArraySolution
的函数是最好的,但是任何人都可以想到更快并解释:)
谢谢
#include <iostream>
#include <vector>
#include <time.h>
#include <map>
void FillVectorRandomly(std::vector<int>& numbers, int size, int lowerRange, int higherRange)
{
if(size == 0)
return;
if(lowerRange < 0)
return;
if(higherRange < lowerRange)
{
int temp = lowerRange;
lowerRange = higherRange;
higherRange = temp;
}
srand(time(NULL));
int dif = higherRange - lowerRange+1;
for(int i = 0; i < size; ++i)
numbers.push_back((rand() % dif) + lowerRange);
}
int MapSolution(std::vector<int>& numbers)
{
std::map<int, int> mapNumbers;
for(int i = 0; i < numbers.size(); ++i)
{
mapNumbers[numbers[i]] = mapNumbers[numbers[i]] + 1;
}
for(int i = 0; i < numbers.size(); ++i)
{
if(mapNumbers[numbers[i]] == 1)
return numbers[i];
}
return -1;
}
int ArraySolution(std::vector<int>& numbers)
{
for(int i = 0; i < numbers.size(); ++i)
{
if(numbers[i] != -1)
{
int count = 0;
for(int j = i+1; j < numbers.size(); ++j)
{
if(numbers[j] == numbers[i])
{
numbers[j] = -1;
count++;
}
}
if(count == 0)
return numbers[i];
}
numbers[i] = -1;
}
}
int main()
{
std::vector<int> numbers;
FillVectorRandomly(numbers, 4, 0, 5);
int m = MapSolution(numbers);
int a = ArraySolution(numbers);
return 0;
}
MapSolution
是 O(N log(N)),因为有 N 个插入 O(logN) -- 大小也是 O(NlogN)
ArraySolution
似乎是 O(N^2),因为有 N 个循环的某个 N 个 N 个 - 但 K 可能很好
以下是大小为 O(1) 的 O(N),因为查找是固定的:
int lookup_solution(std::vector<int>& numbers)
{
int lookup[10000+1] = {};
for (int i=0; i<numbers.size(); ++i)
{
lookup[numbers[i]]++;
}
for (int i=0; i<numbers.size(); ++i)
{
if (lookup[numbers[i]] == 1)
{
return numbers[i];
}
}
return -1;
}
它利用了输入范围仅为 10000 的事实,因此有 N 个插入为 O(1):
•提供的数字介于 0 - 10,000 之间
编辑:如评论(我的版本)中所述,对于较大的输入向量:
int lookup_solution(std::vector<int>& numbers)
{
static const int max_value=10000;
int count[max_value+1] = {}; // counts occurrences of index
int order[max_value+1]; // keeps order of values seen
int index[max_value+1]; // index into order for where order is found
int order_index=0;
for (int i=0; i<numbers.size(); ++i)
{
int n=numbers[i];
int seen=count[n];
if (seen == 0) // first time
{
count[n]=1;
order[order_index]=n;
index[n]=order_index;
order_index++;
}
else if (seen == 1) // not eligible (-1)
{
count[n]=-1; // use -1 since it might be in a register
order[index[n]]=-1;
} // else do nothing
}
for (int i = 0; i < order_index; ++i)
{
if (order[i] != -1)
{
return order[i];
}
}
return -1;
}
相关文章:
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- std::find,返回所有找到的值的替代方法,而不仅仅是存在重复的向量的第一个值
- 如何仅读取文本文件中的第一个值
- 在C++中,如何在第一个"system()"结束后执行第二个"system()"?
- 查找不在标准中的第一个值::设置<int>最小-最大值
- C++:忽略第一个 cin.ignore 之后的输入
- 在C++中打印多个矢量的第一个值
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- C++第一个cout将不会打印
- 我们可以在第一个else-if条件结束后使用另一个else-if条件吗
- 我必须更改我的数字最后一个数字和第一个数字,但不要使用仅带有整数或循环的函数.例如从 12345 到 52341
- OpenGL:第二个VBO破坏了第一个VBO
- 将一个数字拆分为多个数字,每个数字只有一个有效位
- 为什么第一个Dynamic_cast没有投射到基类?
- OpenGL 2D游戏只绘制第二个精灵纹理而不是第一个
- C++ 为什么程序只读取第一个值
- 在我的第一个C++程序中需要一些帮助(简单)
- 为什么我的代码在第一个 if 语句处中断?
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 在将字符串转换为整数后,是否有一种方法可以保持数字的第一个零