1)题目:已知一个整数序列A=(a0,a1...an),其中0<=ai<n(0<=i<n),若存在ap1=ap2.....=apm=x,且m>n/2(0<=pk<n,1<=k<m),则称x为A的主元素,例如A=(0,5,5,3,5,7,5,5),则5为主元素;又如A=(0,5,5,3,5,1,5,7),则A中没有主元素,假设A中的n个元素存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素,则输出该元素,否则输出-1。
2)思路与代码:
源码中使用到的ArrrayList,是调用的是自己实现的ArrayList,自己实现的ArrayList源码地址:https://blog.youkuaiyun.com/u012441545/article/details/89667486
package com.sam.datastruct.arrayList;
import java.util.HashMap;
import java.util.Map;
public class P2_12 {
/*
* 思路:
* 时间复杂度O(n)
* 空间复杂度O(1)*/
public Integer function(int[] s){
if (s.length == 0) {
return -1;
}
if(s.length == 1){
return s[0];
}
Map<Integer, Integer> count = new HashMap<>();
for (Integer i : s) {
if (count.containsKey(i)) {
count.put(i, count.get(i) + 1);
}else {
count.put(i, 1);
}
}
for (Integer integer : count.keySet()) {
if (count.get(integer) > s.length / 2) {
return integer;
}
}
return -1;
}
/*
* 思路:当数组中存在某个出现次数大于n/2的时候,将数组中所有不等的数两两消去后剩下的就是该数,不过反之不成立,故需要进行验证
* 时间复杂度O(n)
* 空间复杂度O(n)*/
public Integer function1(int[] s){
int index = 0;
int[] ss = new int[s.length]; //复制s的数据用于最后的验证(在前面会把s中的数据消掉部分,故不能用s进行验证)
for(int i = 1; i < s.length; ++i){
ss[i] = s[i];
if (s[index] != s[i]) { //两个数不相等,需要消去
s[index] = -1;
s[i] = -1;
if (s.length - 1 == i) { //i是最后一个数不需要继续消数据
break;
}
for(int j = index; j <= i + 1; ++j){ //index指向下一个不为-1的数的,由于数组为自然数,故最多在i+1的位置能够找到数据
if (-1 != s[j]) {
index = j;
break;
}
}
}
}
int target = -1;
for(int i = 0; i < s.length; ++i){
if (-1 != s[i]) {
target = s[i];
return target
}
}
if (target != -1) {
int count = 0;
for (int i : ss) {
if (i == target) {
++ count;
}
}
if (count > ss.length / 2) {
return target;
}
}
return -1;
}
public static void main(String[] args) {
P2_12 p = new P2_12();
int size = 100;
int[] s = new int[]{0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,50,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,50,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,50,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5};
/*Random random = new Random();
for(int i = 0; i < size; ++ i){
s[i] = 1 + random.nextInt(2);
}*/
for(int integer : s){
System.out.print(integer + ", ");
}
System.out.println();
long t1 = System.nanoTime();
System.out.println(p.function(s));
System.out.println(System.nanoTime() - t1);
t1 = System.nanoTime();
System.out.println(p.function1(s));
System.out.println(System.nanoTime() - t1);
}
}