題目是這樣的, 陣列是無序的, 可能沒有重複的數,但最多隻可能有乙個重複的數,要求用最快的方法找到是否有重複的數。
乍一想,挺難的,但是其實非常的簡單。
解決辦法:
陣列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
找出陣列中是否有重複的數
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 假金條的數學思想 此演算法題借鑑...
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 如果是,說明這個值就在它對應的下標下,繼續掃瞄 ...