源地址
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;
}