2 19 找出主要元素

2021-07-09 12:13:39 字數 2019 閱讀 3459

大小為

n 的陣列

a,其主要元素是乙個出現次數超過n/

2 的元素(從而這樣的元素最多有乙個)。例如,陣列 3,

3,4,

2,4,

4,2,

4,4

有乙個主要元素,而陣列 3

,3,4

,2,4

,4,2

,4沒有主要元素。如果沒有主要元素,那麼你的程式應該指出來。

下面是求解該問題的乙個演算法概要。

首先找出主要元素的乙個候選元(這是難點)。這個候選元是唯一有可能是主要元素的元素。第二步確定是否這個候選元是主要元素。為了找出候選元,構造第二個陣列

b 。比較a1

和a2 ,如果它們相等則取其中之一加到陣列

b 中;否則什麼都不做;然後比較a3

和a4 ,按同樣的方式處理,其次類推直到讀完這個陣列,然後遞迴的尋找陣列b中的候選元,它也是

a 的候選元. (為什麼?)

a, 遞迴如何終止?

b, 當n是奇數時, 如何處理?

c, 該演算法的執行時間是多少?

d, 我們如何避免使用附加陣列b?

e, 編寫乙個程式求解主要元素.

首先先考慮

n 為偶數的情況。

我們需要回答這樣乙個問題:

b中的候選元也是

a 中的候選元。

反證法假設m

是a的候選元在陣列

b中的出現次數,

n 是陣列

b中其他元素的個數,即: m+

n=m

其中m是陣列b的大小。

顯然,m

而2m+

2n+l

=n其中l 是

ai、a

i+1 不相同的元素個數。

l 所覆蓋的元素最多只有l/

2個a 的候選元。所以說,

a的候選元個數為2m

+l/2

。 2m+

l2−n

2=4m

+n−2

m−2n

−n2=

m−n<0

所以a中候選元的個數要小於n/

2,假設矛盾,證畢。

好了,到此,我們是時候拿起減而治之這個有力的**了。

我們可以將問題

a 化簡為

b,而問題規模減小一半,不斷的重複,直至陣列規模為1或者0。

當然,別忘記

n 為奇數的情況,我們還需要做些小修改。當n

為奇數時,先從前n−

1 個元素中尋找主元:

1. 如果找到主元確實存在,那麼直接返回主元即可。

2. 否則,第

n 個元素可能是主元,我們需要遍歷陣列來確定它是否真的是主元。

對於偶數: t(

n)=t

(n/2

)+n不難解出 o(

n)=n

對於奇數,確認主元存在需要o(

n)的時間,遍歷陣列也需要o(

n)的時間,總之是o(

n)的時間。

最後附上**

bool ismainelement(vector

&v)

if (count>v.size() / 2)

return

true;

else

return

false;

}int findmainelement(vector

&v)

int res = findmainelement(u);

if (v.size() % 2 != 0 && res == -1 && ismainelement(v))

return v.back();

else

return res;

}

219 存在重複元素 II

219.存在重複元素 ii 給定乙個整數陣列和乙個整數 k,判斷陣列中是否存在兩個不同的索引i 和j,使得nums i nums j 並且 i 和 j 的差的絕對值最大為 k。示例 1 輸入 nums 1,2,3,1 k 3 輸出 true 示例 2 輸入 nums 1,0,1,1 k 1 輸出 t...

219 存在重複元素 II

鏈結 給定乙個整數陣列和乙個整數 k,判斷陣列中是否存在兩個不同的索引 i 和 j,使得 nums i nums j 並且 i 和 j 的差的絕對值最大為 k。示例1 輸入 nums 1,2,3,1 k 3 輸出 true示例2 輸入 nums 1,0,1,1 k 1 輸出 true示例3 輸入 n...

219 存在重複元素 II

給定乙個整數陣列和乙個整數 k,判斷陣列中是否存在兩個不同的索引 i 和 j,使得 nums i nums j 並且 i 和 j 的差的絕對值最大為 k。示例 1 輸入 nums 1,2,3,1 k 3 輸出 true 示例 2 輸入 nums 1,0,1,1 k 1 輸出 true 示例 3 輸入...