我想要一个通过2D数组的算法,并保证每列都有不同的数字。如果在阵列中发现了欺骗,则应使用随机数替换。随机数也必须保持唯一性。
如果我们输入一个随机数,整列,应该是唯一的。
是否也可以获得O(N)解决方案?
答案 0 :(得分:1)
我能想到的最好的方法是为每列创建unordered_map<int,bool>
,遍历列,如果第一次看到数字,则将地图设置为true,如果值已经为真,则为一个骗子用随机数替换它。然后检查地图中的随机数并做同样的事情,如果它也是一个骗局,你将不得不再用一个随机数替换它。这个算法会像线性时间一样运行,但是由于随机数欺骗的可能性,它可以无限运行。
伪代码
2d_array // assume M rows by N cols
array_of_hashtables // N length
for each col
for each row
if array_of_hashtables[2d_array[row][col]] == false
set it to true
else
do
set 2d_array[row][col] to random
while array_of_hashtables[2d_array[row][col]] == true
end
end
不是编写伪代码的忠实粉丝,但这是正确的
答案 1 :(得分:1)
制作std::set
并在检查集合大小的同时逐步插入每列的元素。如果大小改变,插入的值不是重复的,如果它只是随机化一个值并再次将其添加到集合中。如果尺寸发生变化,您可以继续。
答案 2 :(得分:0)
只是为了它,这是Alexandru Barbarosie的解决方案的实现:
#include <iostream>
#include <set>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
int L = 3;
int W = 3;
int R = 3;
int a[L][W];
srand(time(NULL));
for (int i = 0; i < L; i++)
{
for (int j = 0; j < W; j++)
{
a[i][j] = rand() % R + 1;
cout << a[i][j] << " ";
}
cout << endl;
}
cout << endl;
set<int> s;
int n = 0;
for (int j = 0; j < W; j++)
{
for (int i = 0; i < L; i++)
{
s.insert(a[i][j]);
if (s.size() != n)
n = s.size();
else
a[i--][j] = rand() % R + 1;
}
s.clear();
n = 0;
}
for (int i = 0; i < L; i++)
{
for (int j = 0; j < W; j++)
cout << a[i][j] << " ";
cout << endl;
}
}