源地址
https://app.codility.com/programmers/lessons/8-leader/equi_leader/
EquiLeader
給定一個含有N個整數的非空數組A.
一個 equi leader 指的是下標S ,數組A被S ( 0 ≤ S < N − 1) 分割爲兩個數組,這兩個數組擁有相同的Leader.
比如:
A[0] = 4
A[1] = 3
A[2] = 4
A[3] = 4
A[4] = 4
A[5] = 2
有兩個 equi leader
- 0, 因爲 (4) 和 (3, 4, 4, 4, 2) 有相同的 leader 4.
- 2, 因爲 (4, 3, 4) 和 (4, 4, 2) 有相同的 leader 4.
寫一個函數,給定一個數組包含N個整數的非空數組A,返回 equi leader的個數.
class Solution {
public int solution(int[] A);
}
比如
A[0] = 4
A[1] = 3
A[2] = 4
A[3] = 4
A[4] = 4
A[5] = 2
函數返回2.
假定:
- N是範圍在 [1…100,000]的整數
- A中的每個元素都是範圍在 [−1,000,000,000…1,000,000,000]的整數
第一步
如果把一個數組分爲兩個子數組,兩個字數組的Leader相等,那麼這子Leader一定和原數組的Leader相等.
那麼可以先求出數組A的Leader,然後依次判斷各個子數組是否含有相同值的Leader.
public int solution(int[] A) {
int count = 0;
Integer leader = getLeader(A);
if (leader == null) {
return count;
}
int N = A.length;
for (int i = 0; i < N - 1; i++) {
int countLeft = 0;
for (int j = 0; j <= i; j++) {
if (A[j] == leader.intValue()) {
countLeft++;
}
}
if (countLeft <= (i + 1) / 2)
continue;
int countRight = 0;
for (int j = i + 1; j < N; j++) {
if (A[j] == leader.intValue()) {
countRight++;
}
}
if (countRight > (N - i - 1) / 2)
count++;
}
return count;
}
Integer getLeader(int[] A) {
int N = A.length;
LinkedList<Integer> stack = new LinkedList<Integer>();
for (int i = 0; i < N; i++) {
if (stack.size() == 0) {
stack.add(A[i]);
} else {
if (stack.getLast() != A[i]) {
stack.removeLast();
} else {
stack.addLast(A[i]);
}
}
}
if (stack.size() == 0)
return null;
int candidate = stack.getLast();
int count = 0;
for (int i = 0; i < N; i++) {
if (A[i] == candidate) {
count++;
}
}
return count > N / 2 ? candidate : null;
}
優化一下
上面的solution中有重複計算的部分.在計算子數組中candidate的個數的時候,不用每一次都從0到N-1計算一邊,只有第一次需要遍歷全部,後面每次移動index的時候判斷當前元素是否等於candidate,然後加上或者建議1 即可.
public int solution(int[] A) {
int count = 0;
Integer leader = getLeader(A);
if (leader == null) {
return count;
}
int N = A.length;
int countLeft = 0;
int countRight = 0;
// calculate the count of leader where index = 0
if (A[0] == leader.intValue())
countLeft++;
for (int i = 1; i < N; i++) {
if (A[i] == leader.intValue())
countRight++;
}
if (countLeft > 0 && countRight > (N - 1) / 2) {
count++;
}
// move the index from 0 to N-1 and calculate the count of leader
for (int i = 1; i < N - 1; i++) {
if (A[i] == leader.intValue()) {
countLeft++;
countRight--;
}
if (countLeft > (i + 1) / 2 && countRight > (N - i - 1) / 2) {
count++;
}
}
return count;
}
Integer getLeader(int[] A) {
int N = A.length;
LinkedList<Integer> stack = new LinkedList<Integer>();
for (int i = 0; i < N; i++) {
if (stack.size() == 0) {
stack.add(A[i]);
} else {
if (stack.getLast() != A[i]) {
stack.removeLast();
} else {
stack.addLast(A[i]);
}
}
}
if (stack.size() == 0)
return null;
int candidate = stack.getLast();
int count = 0;
for (int i = 0; i < N; i++) {
if (A[i] == candidate) {
count++;
}
}
return count > N / 2 ? candidate : null;
}