Java solution to Codility EquiLeader problem (Lesson 8 – Leader) which scored 100%. The problem is to find the two adjoining sub-arrays with the same integer occurring in more than half the elements of each sub-array.
The strategy is:
- find the dominator of entire array with the same code as from the Dominator problem If no Dominator, no equi leaders can exist.
- keep running count of occurrences of dominator at each array index. That way, can calculate if there’s an equi leader pair at every index in given array.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 package com.codility.lesson08.leader;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class EquiLeader {
public int solution(int[] A) {
Stack stack = new Stack();
for(int i=0; i<A.length; i++) {
if(stack.isEmpty()) {
stack.push(A[i]);
}
else {
if(stack.peek().intValue() == A[i]) {
stack.push(A[i]);
}
else {
stack.pop();
}
}
}
//no equi leaders if stack is empty
if(stack.isEmpty()) return 0;
int candidate = stack.peek().intValue();
int dominatorCount = 0;
Map<Integer, Integer> dominatorMap = new HashMap<Integer, Integer>();
for(int i=0; i<A.length; i++) { if(A[i] == candidate) { dominatorCount++; dominatorMap.put(i, dominatorCount); } } //works for even and odd number of A elements //e.g. if A.length = 4, count needs to be > 2
//e.g. if A.length = 5, count needs to be > 2
int equiLeaders = 0;
if(dominatorCount > (A.length / 2)) {
//find all equi leader sequences
int lastCandidateOccurenceIndex = 0;
int runningDominatorCount = 0;
for(int i=0; i<A.length-1; i++) { if(A[i] == candidate) { lastCandidateOccurenceIndex = i; runningDominatorCount = dominatorMap.get(i).intValue(); } else if(dominatorMap.get(lastCandidateOccurenceIndex) != null) { runningDominatorCount = dominatorMap.get(lastCandidateOccurenceIndex).intValue(); } if(runningDominatorCount > (i+1)/2) {
if((dominatorCount - runningDominatorCount) > (A.length - (i+1))/2 ) {
equiLeaders++;
}
}
}
}
return equiLeaders;
}
}
TestNG test cases for this problem which all passed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 package test.com.codility.lesson08.leader;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.codility.lesson08.leader.EquiLeader;
public class EquiLeaderTests {
private EquiLeader solution;
@BeforeTest
public void setUp() {
solution = new EquiLeader();
}
@DataProvider(name = "test1")
public Object [][] createData1() {
return new Object [][] {
new Object [] { new int [] { 4, 3, 4, 4, 4, 2 }, 2 },
new Object [] { new int [] { 1, 5, 1, 5, 5, 5, 5, 5 }, 3 },
new Object [] { new int [] { 1, 1, 1, 1, 1, 1 }, 5 },
new Object [] { new int [] { 4, 4, 2, 5, 3, 4, 4, 4 }, 3 },
new Object [] { new int [] { 1, 2, 3 }, 0 },
new Object [] { new int [] { 1000000000 }, 0 },
new Object [] { new int [] { 1000, 1 }, 0 },
new Object [] { new int [] { 0, 0 }, 1 },
};
}
@Test(dataProvider = "test1")
public void verifySolution(int [] pA, int pExpected) {
Assert.assertEquals(solution.solution(pA), pExpected);
}
}