源地址
https://app.codility.com/programmers/lessons/8-leader/dominator/
Dominator(支配者)
對於一個給定的整數數組, "支配者"是在這個數組中出現的頻率超過一半的整數.
例如:
A[0] = 3 A[1] = 4 A[2] = 3
A[3] = 2 A[4] = 3 A[5] = -1
A[6] = 3 A[7] = 3
數值"3"出現過5次, 5/8 > 0.5, 所以數值"3"是一個"支配者";
而在這個數組中, 這個"支配者"出現在數組下標:
0, 2, 4, 6 , 7.
請寫一個函數
class Solution {
public int solution(int[] A);
}
對給定數組返回其任意一個支配者的數組下標。
例如,對上述數組,函數可以返回0,2,4,6,7中的任意一個。 如果沒有支配者,函數應該返回 −1。
假定:
- N 是 [0…100,000] 內的 整數;
- 數組 A 每個元素是取值範圍 [−2,147,483,648…2,147,483,647] 內的 整數 .
第一步
先排序,如果有Leader,那麼肯定Leader肯定是在排序之後的中間.去除中間的元素進行計數.
public int solution(int[] A) {
int N = A.length;
if (N == 0) {
return -1;
}
int[] B = A.clone();
Arrays.sort(B);
int candidate = B[N / 2];
int count = 0;
int result = 0;
for (int i = 0; i < N; i++) {
if (A[i] == candidate) {
count++;
result = i;
}
}
return count > N / 2 ? result : -1;
}
優化一下
根據 教程 , 可以通過自定義stack來尋找Leader,按照順序往Stack中放元素,當後一個和前一個不等時,刪除這兩個,最後剩下的就是Leader.
public int solution(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 -1;
int candidate = stack.getLast();
int count = 0;
int result = 0;
for (int i = 0; i < N; i++) {
if (A[i] == candidate) {
count++;
result = i;
}
}
return count > N / 2 ? result : -1;
}