one of the halves. So we can recursively find all 1
/
3plurality elements in each of the halves, and in the end
we have at most 4 candidates. We can check whether they are truly a 1
/
3plurality by just counting how
many times they occur in the full array, in
O
(
n
)
time.
Algorithm:
Here is the complete algorithm.
Algorithm FindPlurality
(
A
[
0
..
n

1
])
:
1. If
n
=
1 return
{
A
[
0
]
}
.
2. If
n
≥
2:
3.
Let
k
:
=
b
n
/
2
c
.
4.
Let
C
:
=
/0. (“This will be the set of candidates.”)
5.
Let
M
:
=
/0. (“This will be the set of 1
/
3plurality elements.”)
6.
Call FindPlurality
(
A
[
0
..
k

1
])
and add the results to
C
.
7.
Call FindPlurality
(
A
[
k
..
n

1
])
and add the results to
C
.
8.
For each
x
in
C
:
9.
Count the number of occurences of
x
in
A
[
0
..
n

1
]
.
10.
If this number is greater than
n
/
3, add
x
to
M
.
11.
Return
M
.
Running time:
The running time is
O
(
n
lg
n
)
. The total number of items returned by each call can be at most
2, since there can be at most two 1
/
3plurality elements in any array. Therefore
C
can have size at most
4, which means that line 9 gets executed at most 4 times, each time taking
O
(
n
)
time. Now if
T
(
n
)
is the
running time of the algorithm for an array of size
n
, then we just proved that
T
(
n
) =
2
T
(
n
/
2
)+
O
(
n
)
.
By appealing to the master theorem, we can see that this results in a running time of
O
(
n
lg
n
)
.
Proof of correctness:
We will be inductively proving that the algorithm returns all 1
/
3plurality elements in
the given array. Let
P
(
n
)
denote the assertion that, for all arrays
A
of length
n
, FindPlurality
(
A
[
0
..
n

1
])
correctly returns all 1
/
3plurality elements of
A
. We want to prove
∀
n
∈
N
.
P
(
n
)
. We will prove it by strong
induction on
n
.
CS 170, Fall 2014, Sol 2
7
Base case: the base case of the induction is when
n
=
1, and in that case the single element in the array is a
1
/
3plurality which is returned by the algorithm (line 1). Thus, we have proven
P
(
1
)
.
Inductive step: We need to prove
P
(
1
)
∧ ··· ∧
P
(
n

1
) =
⇒
P
(
n
)
. Since we run over all elements of
C
and check whether they are in fact 1
/
3plurality elements, there is no risk that FindPlurality will return
something that isn’t a 1
/
3plurality element. We just need to show that each true 1
/
3plurality element
x
does get inserted into
C
. Consider one such element
x
. If
x
does not get added to
C
in line 6, it means that it
was not a 1
/
3plurality in
A
[
0
..
k

1
]
, so it appeared at most
k
/
3 many times in that part (since
k
<
n
and the
inductive hypothesis promises that FindPlurality works correctly on an array of size
k
). Similarly if it does
not get added in line 7, it means that it appeared at most
(
n

k
)
/
3 many times in
A
[
k
..
n

1
]
. So overall, the
number of times it can appear in
A
[
0
..
n

1
]
is at most
k
/
3
+ (
n

k
)
/
3
=
n
/
3. But this is in contradiction
with the assumption that
x
was a 1
/
3plurality element. So every 1
/
3plurality element will be added to
C
in either line 6 or line 7, and thus will be returned by FindPlurality.