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.
[cc lang="java" escaped="true"] 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; } } [/cc]
TestNG test cases for this problem which all passed:
[cc lang="java" escaped="true"] 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); } } [/cc]