[英]fill an array in Java of size n with unique random numbers with complexity O(n)
我必须编写代码来填充大小为n的数组,其中包含0-10n
(含)范围内的唯一随机数。 我可以用O(n^2)
复杂度做到这一点,但我需要用O(n)
复杂度来做。 我想不出一种不涉及生成随机数的方法,然后返回部分填充的数组来检查数组中是否有重复项。
作为参考,这是我的方法的O(n^2)
版本:
private static void fillWithUniqueN2(int[] numbers)
{
Random rng = new Random();
for (int i = 0; i < numbers.length; i++)
{
boolean added = false;
while (!added)
{
int newNumber = rng.nextInt(numbers.length);
boolean unique = true;
for (int j = 0; j < i; j++)
{
if (newNumber == numbers[j])
{
unique = false;
}
}
if (unique)
{
numbers[i] = newNumber;
added = true;
}
}
}
}
用于在一定范围内生成唯一随机数的标准解决方案是:
生成范围内所有数字的列表 - O(n)
洗牌清单 - O(n)
从列表中提取前N个项目 - O(1)或O(n)
因此整个操作将是O(n)。
要在O(n)中对整个列表进行洗牌,您可以使用Fisher-Yates shuffle
:
-- To shuffle an array a of n elements (indices 0..n-1):
for i from 0 to n−2 do
j ← random integer such that i ≤ j < n
exchange a[i] and a[j]
作为奖励,它已经在Collections.shuffle()
(文档提到它在线性时间运行)。
package stackOverflow;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class FisherYates
{
public static void main(String[] args) {
int n = 10;
IntStream range = IntStream.rangeClosed(0, n * 10);
List<Integer> integers = range.boxed().collect(Collectors.toList());
Collections.shuffle(integers);
System.out.println(integers.subList(0, n));
}
}
例如,它输出:
[28, 44, 26, 94, 21, 65, 55, 25, 99, 93]
[40, 57, 3, 42, 61, 26, 64, 45, 19, 41]
...
保留已输入的一Set
条目。 对于每个候选人,检查Set
是否已包含该条目。 如果没有,将它添加到数组和Set
(假设您的检查没有同时添加到Set
),否则生成一个新的候选。 重复每个候选人,直到成功,然后继续到阵列中的下一个打开的插槽。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.