簡體   English   中英

這是一種有效的算法嗎?

[英]is this an efficient algorithm?

嗨,這是我的算法,該算法采用之前已排序的帶有浮點數的數組。因為我曾考慮過,當我們在使用此算法之前對數組進行排序時,其最壞情況下的性能為O(nlogn),但不進行排序的情況下將為O( n ^ 2)。所以我認為該算法可以找到一個重復的數字,對嗎?

1     Algorithm Duplicate_Number(a , n)
2     // Find one duplicate number in a[1 :n ]
3     {
4              temp: = a [0];
5              while (i<n) do
6              {
7                     if (temp=a[i])
8                     {
9                           return a[i]; break;
10                    }
11                    else
12                         temp: =a [++i];
13           }

好吧,您從來沒有定義過“ i”,但是如果您對數組進行了排序,那么它將對任何完全有序的類型都有效(一種對集合只有正確的排序順序的類型),而float就是這種類型。

浮點數很少彼此完全相等,尤其是如果它們事先經過任何實際的計算步驟。 通常最好檢查一下浮點數是否在彼此的小范圍內,以處理由於舍入而導致的一些不可避免的錯誤。 如果您沒有提前執行計算步驟,而只是接受輸入,則應該可以使用。

您熟悉哈希表嗎? 這個問題可以在O(n)時間內解決。 您不需要對數組進行排序,因此無需花費O(n lg n)的時間對其進行排序。 對於每個元素,檢查它是否已經在哈希表中; 如果是,則返回它,如果不是,則將其插入哈希表。 插入和讀取操作在哈希表上是O(1)(分攤,並假設哈希函數很好),因此應該可以滿足您的需求。 哈希表無法進行近似等式匹配,盡管哈希表僅對精確值查找有用,因為它們不會按排序順序保留數據。

完全通用的Java實現,適用於定義了有意義的哈希函數和有意義的equals的任何類型(假定Object的默認引用行為是錯誤的):

import java.util.HashSet;

class DuplicateValue{
    public static <T> duplicateValue(T[] values){
        HashSet<T> store = new HashSet<T>();
        for(T item : values){
            if(store.contains(item)){
                return item;
            }
            store.add(item);
        }
        return null; //no duplicate found
    }
}

這實際上適用於任何數據類型,因為Java提供了內置的HashCode和Equals函數。 就是說,如果您使用的是自定義數據類型,請確保覆蓋.hashCode和.equals,以便提供有意義的結果。 float不是對象,但是可以自動裝箱到Float中。

您沒有初始化我。

完成后,遍歷數組,比較兩個“鄰居”。

另外,由於您使用的是浮點數,因此您可能要考慮兩個數字是否足夠接近...盡管這對於您的算法不是必需的,但是如果這些數字是通過某些計算生成的,則可能會很有用。 例如,您可以使用一些epsilon = 0.000000000000000001或smt。

因此,與您的算法非常相似的算法可能是:

i:= 1
tmp:= a[0];
while(i < n) {
    if(a[i] = tmp) {
        print "duplicate number: " + tmp
        break
    } else {
        tmp:=a[i]
        i++
    }
}

PS:是的,對數組進行排序是個好主意。 使用排序數組時,這段代碼的復雜度為O(n)。

從理論上講,可以通過將到目前為止檢查的所有數字存儲在散列中並在每次迭代中查找該算法,將算法設為O(n)。 給定查找為O(1),可以認為查找速度更快。

實際上,加速取決於散列函數的速度和可用於存儲其他數據的內存。

考慮到會迫使其始終在循環的第一次迭代后完成的錯誤,因此性能將比您預期的好得多。 我想你想要的是i++ ,而不是++i

一個更簡單的for循環將同樣有效,但可讀性更高:

for(int i=1; i<n; i++)
{
  if(a[i] == a[i-1])
    return a[i];
}

編輯:-此示例使用C語法,但是大多數語言都有一個for循環等效項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM