問題:在乙個規模為n的陣列array[n]中,所謂主元素就是出現次數大於n/2的元素,例如
3.3.4.2.4.4.2.4.4 有乙個主元素為4。
給出乙個演算法,如果過半元素存在,就找出來,否則給出報告,要求給出o(n)的演算法。
常規想法
(1) 窮舉:找出元素中每乙個數在資料中的數量。時間複雜度o(n^2)
(2) 排序:先對陣列快排,然後重頭開始遍歷一遍計算每個數的數量。時間複雜度o(n*logn+n)
經典演算法裁剪陣列演算法,
時間複雜度為o(2n )
思想: 如果乙個陣列array[n],其中有兩個元素e1和e2。
(1) e1不等於e2
假如e1是陣列array[n]的主元素,e2不是。那麼e1在array[n]中的數量en>n/2。此時去掉array[n]中的e1和e2兩個元素(e1!=e2)。那麼新陣列array[n-2]中e1的數量為en-1,並且en-1>n/2-1=(n-2)/2。即e1還是新陣列array[n-2]的主元素。
假如e1和e2都不是陣列array[n]的主元素,那麼去掉e1、e2以後。那麼新陣列的大小將變成n-2。此時很有可能出現乙個新陣列的主元素x,此主元素x的數量正好等於x=(n-2)/2+1。但是該主元素就不是原陣列的主元素了,因為x=
(n-2)/2+1=n/2。那麼這樣的主元素x我們叫做偽主元素。因此需要通過和裁剪掉元素比較,來確定是否是真正的主元素。
(2) e1等於e2
這種情況下不能進行裁剪。只能繼續找不同的兩個數裁減掉
#include#include// 演算法源**,裁剪當前陣列中相鄰的不同元素void main();
int arrlength=6; //陣列長度
int element=parr[0];
int value=1; //記錄剪裁過程中遇到相同元素的個數
int delnum=0; //記錄裁剪陣列的元素個數
int *darr=(int *)malloc(arrlength*sizeof(int)); //記錄被剪裁的陣列元素
int dtop=0; //當前剪裁陣列的索引位置
for(int i=1;i0)
} //如果裁剪之後出現了主元素,那麼這個主元素有可能是個偽主元素
if(value>(arrlength-delnum)/2)
經典問題 找乙個陣列中的主元素
問題 在乙個規模為n的陣列array n 中,所謂主元素就是出現次數大於n 2的元素,例如 3.3.4.2.4.4.2.4.4 有乙個主元素為4。給出乙個演算法,如果過半元素存在,就找出來,否則給出報告,要求給出o n 的演算法。常規想法 1 窮舉 找出元素中每乙個數在資料中的數量。時間複雜度o n...
乙個陣列中找重複數
乙個大小為n的陣列,裡面的數都屬於範圍 0,n 1 有不確定的重複元素,找到至少乙個重複元素,要求o 1 空間和o n 時間。include const int no repeat flag 1 int findrepeatnumberinarray int a,int n return no re...
刪除乙個陣列中重複的元素
從別人那裡聽來的,作為原創,哈哈哈。刪除乙個陣列中重複的元素,只保留第乙個 var testarray 手機字首 省市 null 1354552.0 廣東深圳 null 1388888.0 雲南昆明 null 1388888.0 雲南dd null 迴圈方法一 inarray testarray j...