找出陣列中是否有重複的數

2021-05-27 01:46:15 字數 2594 閱讀 6304

2010-09-09 23:03:59|  分類: c&c++ |  標籤:c   |字型大小大中小 訂閱

陣列a[n],1至n-1這n-1個數存放在a[n]

中,其中某個數重複一次。寫乙個函式,找出被重複的數字。時間複雜度必須為o(n)函式原型:

int do_dup(int a,int n)

××××××××××××××××××××××××××××××××××

假金條的數學思想

此演算法題借鑑了假金條的思想,不過比那個過程簡單,存放

1至n-1

,就相當於依次從各個袋中取出1至n-1個金條,但是有乙個是重的,計算這n個數的和將相當於稱總重量,減去1至n-1

的和(用數學方法求)就可求出來重複的數。總之要充分利用數學知識

const int n = 5;

int a[n]=;

int tmp1 = 0;

int tmp2 = 0;

for (int i=0; i

printf("重複的數:%d\n",n-(tmp1-tmp2));

上述方法求1~n的和,減去陣列總和,即為n-x 的差值,x為待找的數

可以優化的是1-n的和不用程式算,數學方法直接算了

可定義乙個巨集,

#define sum(x)  (x(x+1)/2)

當然乘法操作是比較複雜的,當n較小時加幾個數的效率可能更高

××××××××××××××××××××××××××××××××××

標誌陣列法

申請乙個長度為n-1且均為'0'組成的字串。然後從頭遍歷a[n]陣列,取每個陣列元素a[i]

的值,將其對應的字串中的相應位置置1,如果已經置過1的話,那麼該數就是重複的數。就是用位圖來實現的。

其實,只要數還是0 -- n-1裡面的數,那麼可以用這樣的方法判斷所有的重複數的位置和值。

比如這樣的乙個陣列

我們生成乙個字串"000";

然後開始遍歷,a[0] = 2;

所以,字串的第二位為"0",那麼我們將其置為"1"

字串為"010"

重複,字串為"011",,,,,"111"

然後,判斷a[3] = 2 那麼 第二位為"1"

所以,a[3]為重複數,並且位置為第4位。

上述map

等各方法的思路是一致的,即訪問過後做標記,再次訪問時即可知道是否重複。如果考慮空間複雜度的話,其空間

o(n)

int do_dup(int arr,int num)

} ××××××××××××××××××××××××××××××××××

固定偏移標誌法

利用標記法單純寫個o(n)的方法並不難,關鍵是如何保證兩點:

不改變a的初始值

函式內不開闢另外的o(n)記憶體空間.

很明顯上述方法申請了o(n)記憶體空間,當n過大時,效能降低了

因此應利用a[n]本身中值和下標的關係來做標記,處理完成後再清除標記即可

a[n],裡面是1至n-1。原陣列a[i]最大是n-1,若a[i]=k在某處出現後,將a[k]加一次n,做標記,當某處a[i]=k再次成立時,檢視a[k]即可知道k已經出現過。a[i]在程式中最大也只是n-1+n=2n-1

(溢位了怎麼辦啊???),此為乙個限制條件

int do_dup(int arr,int num)

else

} printf("無重複");

return -1;

}上面就是時間複雜度o(n), 空間複雜度o(1)的演算法!

××××××××××××××××××××××××××××××××××

符號標誌法

上述方法將元素加乙個固定的num來做標記,可能會造成溢位。下列方法中利用符號位來做標記,因為1~n都為正值,所以就無限制了。基本思想是用int陣列的符號位作雜湊表。(反正不是unsigned int符號位閒著也是閒著)

bool dup(int array,int n)

else

}else // |array[i]|代表的值已經出現過一次了

else }}

return -1;//沒有重複

} //用於修復陣列

void restorearray(int array,int n)

}時間複雜度o(n) 空間複雜度o(1)

不過時間複雜度o(n) 空間複雜度o(1)不只乙個重複利用此法也是可以實現的

//附上修改後的演算法

bool do_dup_mal(int arr, int n, int *pre, int *back)

char *arrayflag = new char[max+1] ;

if (null == arrayflag)

return -1;

//while(i++ < max) arrayflag[i] = '\0';

memset(arrayflag, 0, max+1 ); // '\0' == 0

for(i=0; i

有錯.需改

**:

找出陣列中是否有重複的數

題目是這樣的,陣列是無序的,可能沒有重複的數,但最多隻可能有乙個重複的數,要求用最快的方法找到是否有重複的數。乍一想,挺難的,但是其實非常的簡單。解決辦法 陣列a n 1 至n 1 這n 1 個數存放在 a n 中,其中某個數 重複一次 寫乙個函式,找出被重複的數字。時間複雜度必須為o n 函式原型...

PHP 判斷陣列中是否有重複值並找出重複值

可以用來測試需要唯一憑據號碼的,是否有重複值,不過一般直接使用uuid了,簡單粗暴就解決問題,這個就簡單的測試生成的資料是否有重複值吧 author wyy date 2019 01 09 13 34 16 email 2752154874 qq.com last modified by wyy l...

找出陣列重複的數

1 在乙個長度為 n 的陣列裡的所有數字都在 0 n 1 的範圍內,找出任意乙個重複的數。簡明思路 按照題目要求,如果這個陣列裡面的數恰好沒有重複的數,則陣列下標跟對應的值相等。否則,當掃瞄到下標為 i 的數字時,比較這個下標的值 m 是不是等於 i 如果是,說明這個值就在它對應的下標下,繼續掃瞄 ...