在时间复杂度O(n)和空间复杂度O(1)中查找数组中重复元素的最有效算法是什么? 时间复杂度O(n)空间复杂度O(1)

注意-您不能使用收藏集或地图

我已经尝试过了,但这没有复杂度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,3,1}; 
        int arr_size = arr.length; 
        repeat.printRepeating(arr,arr_size); 
    } 
} 

有没有一个解决方案的人,可以找到一个不使用Collection或Map且只使用单个for循环的重复数组

saraxiaoxi 回答:在时间复杂度O(n)和空间复杂度O(1)中查找数组中重复元素的最有效算法是什么? 时间复杂度O(n)空间复杂度O(1)

如果大小为n的数组中的元素在0 ~ n-1(或1 ~ n)的范围内。

我们可以尝试通过对每个a[i]放置i到索引a[i] != i来对数组进行排序,如果发现索引{{ 1}},表示存在另一个值为a[i]的元素。

i

由于每次交换之后,其中一个元素将处于正确的位置,因此最多将进行n次交换操作。

时间复杂度O(n)

空间复杂度O(1)

,

好吧,因此您对类型int的数组有恒定的存储需求吗?
没问题,让我们使用一个大(但恒定)的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;
    }    
}

由于我们仅对数组进行一次迭代,因此时间复杂度为O(n)(其中n是数组中元素的数量)。
而且由于我们总是使用相同数量的空间,因此内存复杂度为O(1),这与任何事物无关。

,

由于这些是int,因此您可以使用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 : ",""))
        );
}

请注意(根据评论)负值需要单独处理,否则您可能会遇到IndexOutOfBoundsException

,

只是一个for循环,i将在j位于数组末尾,当前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();
    }
本文链接:https://www.f2er.com/3145203.html

大家都在问