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 如果是,說明這個值就在它對應的下標下,繼續掃瞄 ...