在带有边界的整数数组中查找重复项

时间:2010-08-08 15:56:38

标签: algorithm duplicates

以下是我编写的问题描述和算法。有什么办法可以改进这个算法吗?

给定一个未知大小的整数数组,只包含0到30之间的数字,编写一个函数来返回一个包含所有重复项的整数数组。

int[] findDupes(int[] array) {
    int[] found = new int[30];
    int[] dupes = new int[30];
    int dupesCount = 0;
    for (int i = 0; i < array.length; i++) {
        if (found[array[i]] <= 1) {
            found[array[i]]++;              
        }else{
            continue;
        }
        if(found[array[i]] > 1){
            dupes[dupesCount++] = array[i];
            if (dupesCount == 30)
                break;
        }
    }
    if (dupesCount == 0)
        return new int[0];
    return dupes;
}

假设运行此算法的最佳情况是n或30,以较低者为准 运行此算法的最坏情况是n,因为我必须扫描整个数组以查找重复项。有什么意见吗?

4 个答案:

答案 0 :(得分:2)

你有正确的想法,但问问自己,这个块做了什么,确切

    if(found[array[i]] > 1){
        dupes[dupesCount++] = array[i];
        if (dupesCount == 30)
            break;
    }

什么时候开火?

使用几个样本遍历您的代码,包括1000次出现0的数组。

你究竟回来了什么?为什么你需要特殊情况0。

同样最佳的案例运行时间将大于30.在达到结束之前停止的最小输入是什么?

答案 1 :(得分:1)

需要更精确地定义问题。是否只有1或2次出现整数?可能有0或3次出现?

如果只有1或2次出现整数,则整数范围为1到30;我会有一个BitSet,当我找到一个整数时翻转该位。当我读完原始数组时,0的所有位将代表包含重复数的整数。

答案 2 :(得分:0)

奇怪的是:

    if (found[array[i]] <= 1)              
    }else{
        continue;//happens if found[array[i]] > 1
    }
    if(found[array[i]] > 1){//usually don't get here, because of continue

继续修复只添加一次数字吗?虽然它有效,但代码具有误导性。

如果只有一个副本,你是否必须返回一个30长度的数组?

我建议通过拆分任务来使代码更慢更好。

答案 3 :(得分:0)

这里是嵌入了注释的修改版本。

int[] found = new int[3];
    int[] dupes = new int[3];
    int dupesCount = 0;
    for (int i = 0; i < array.length; i++) {
        if (found[array[i]] <= 1) {
            found[array[i]]++;              
        }
        if(found[array[i]] > 1){ //duplicate found
            dupes[dupesCount++] = array[i];

            // if 30 duplicate are found don't scan the array any more
            // since the distinct numbers are only 30
            if (dupesCount == 30) 
                break;
        }
    }
    if (dupesCount == 0)
        return null;
    return dupes;