[英]What is the most efficient algorithm to find repeated elements in an array in time complexity O(n) and space complexity O(1)?
Note- You can not use Collection or Map注意 -您不能使用 Collection 或 Map
I have tried this but this is not having complexity O(n)我已经尝试过了,但这没有复杂性 O(n)
class RepeatElement
{
void printRepeating(int arr[], int size)
{
int i, j;
System.out.println("Repeated Elements are :");
for (i = 0; i < size; i++)
{
for (j = i + 1; j < size; j++)
{
if (arr[i] == arr[j])
System.out.print(arr[i] + " ");
}
}
}
public static void main(String[] args)
{
RepeatElement repeat = new RepeatElement();
int arr[] = {4, 2, 4, 5, 2, 3, 1};
int arr_size = arr.length;
repeat.printRepeating(arr, arr_size);
}
}
Is any one having solution for solving,to find a duplicate array without using Collection or Map and using only single for loop是否有任何人有解决方案,在不使用 Collection 或 Map 并且仅使用单个 for 循环的情况下找到重复数组
If the elements in an array with size n
are in a range of 0 ~ n-1
( or 1 ~ n
).如果数组中大小
n
的元素在0 ~ n-1
(或1 ~ n
)的范围内。
We can try to sort the array by putting a[i]
to index i
for every a[i] != i
, and if we find that there is already an a[i]
at index i
, it means that there is another element with value a[i]
.我们可以尝试通过将每个
a[i] != i
a[i]
放入索引i
来对数组进行排序,如果我们发现索引i
处已经有一个a[i]
,则意味着还有另一个元素具有值a[i]
。
for (int i = 0; i < a.length; i++){
while (a[i] != i) {
if (a[i] == a[a[i]]) {
System.out.print(a[i]);
break;
} else {
int temp = a[i]; // Putting a[i] to index i by swapping them
a[i] = a[a[i]];
a[temp] = temp;
}
}
}
Since after every swap, one of the elements will be in the right position, so there will be at most n swap operations.由于每次交换后,其中一个元素都会在右边的 position 中,所以最多会有 n 次交换操作。
Ok, so you have a constant memory requirement for an array of type int
?好的,所以您对
int
类型的数组有恒定的 memory 要求?
No problem, just let's use a large (but constant) byte
array:没问题,让我们使用一个大的(但不变的)
byte
数组:
byte[] seen = new byte[536870912];
byte[] dups = new byte[536870912];
for (int i : arr) {
int idx = i / 8 + 268435456;
int mask = 1 << (i % 8);
if ((seen[idx] & mask) != 0) {
if ((dups[idx] & mask) == 0) {
System.out.print(i + " ");
dups[idx] |= mask;
}
} else {
seen[idx] |= mask;
}
}
As we only iterate once over the array, we have a time complexity of O(n) (where n is the number of elements in the array).由于我们只在数组上迭代一次,我们的时间复杂度为 O(n)(其中 n 是数组中元素的数量)。
And because we always use the same amount of space we have a memory complexity of O(1), that is independent of anything.因为我们总是使用相同数量的空间,所以我们有一个 O(1) 的 memory 复杂度,这与任何事情无关。
As these are int
s, you could use a BitSet
:由于这些是
int
s,您可以使用BitSet
:
void printRepeating(int arr[], int size) {
BitSet bits = new BitSet();
BitSet repeated = new BitSet();
//to deal with negative ints:
BitSet negativeBits = new BitSet();
BitSet negativeRepeatedBits = new BitSet();
for(int i : arr) {
if(i<0) {
i = -i; //use the absolute value
if(negativeBits.get(i)) {
//this is a repeat
negativeRepeatedBits.set(i);
}
negativeBits.set(i);
} else {
if(bits.get(i)) {
//this is a repeat
repeated.set(i);
}
bits.set(i);
}
}
System.out.println(
IntStream.concat(negativeRepeatedBits.stream().map(i -> -i), repeated.stream())
.mapToObj(String::valueOf)
.collect(Collectors.joining(", ", "Repated Elements are : ", ""))
);
}
Note that (as per comment) negative values need to be treated separately, as otherwise you could be faced with IndexOutOfBoundsException
.请注意(根据评论)负值需要单独处理,否则您可能会遇到
IndexOutOfBoundsException
。
Just one for loop, i
will increment when j
is at the end of the array, the current arr[i]
is found earlier of a new duplicate element is found只有一个 for 循环,当
j
位于数组末尾时i
将递增,当前arr[i]
较早找到新的重复元素
void printRepeatingSingleLoop(int arr[], int size)
{
int i, j, k;
System.out.println("Repeated Elements are :");
for (i = 0, j = 1, k = 0; i < size; )
{
if (k < i ) {
if (arr[i] == arr[k]) {
i++;
j = i+1;
k = 0;
} else {
k++;
}
} else {
if (j == size) {
i++;
j = i + 1;
k = 0;
} else {
if (arr[i] == arr[j]) {
System.out.print(arr[i] + " ");
i++;
j = i + 1;
k = 0;
} else {
j++;
}
}
}
}
System.out.println();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.