您的位置:首页 > 职场人生

面试题29:数组中出现次数超过一半的数字

2012-05-08 10:53 483 查看
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。


分析:

如果一个数字才数组中出现的次数超过了数组长度的一半,那么对这个数组进行排序,位于数组中间位置的那个数就是出现次数超过一半的那个数。对数组排序的时间复杂度是O(nlog(n)),但是对于这道题目,还有更好的算法,能够在时间复杂度O(n)内求出。我们写过快速排序算法,其中的Partition()方法是一个最重要的方法,该方法返回一个index,能够保证index位置的数是已排序完成的,在index左边的数都比index所在的数小,在index右边的数都比index所在的数大。那么本题就可以利用这样的思路来解。

通过Partition()返回index,如果index==mid,那么就表明找到了数组的中位数;如果index<mid,表明中位数在[index+1,end]之间;如果index>mid,表明中位数在[start,index-1]之间。知道最后求得index==mid循环结束。

根据求得的index,遍历一遍数组,每当出现一个等于index所指向的数时time++,最后判断time是否大于数组长度的一半,如果大于则表明index所指向的数就是所求的数,如果不是,则表明不存在一个数出现的次数超过数组长度的一半。

代码实例:

View Code

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Iterator;
import java.util.LinkedList;

public class GetMoreThanHalfWords {

public static void main(String args[]) {
GetMoreThanHalfWords gmthw = new GetMoreThanHalfWords();

LinkedList<String> list =new LinkedList<String>();
gmthw.buildLinkedList(list);
//两种输出LinkedList的方法
//gmthw.printLinkedList(list);
//gmthw.printLinkedList2(list);
System.out.println(gmthw.getMoreThanHalf(list));

/**
* 测试String的compareTo方法
String a="apple";
String b="orange";
System.out.println(a.compareTo(b));
System.out.println(b.compareTo(a));
*/

}

// 第一步:创建LinkedList,将文件中的单词保存到LinkedList当中。
public void buildLinkedList(LinkedList<String> list) {
try {
FileReader reader = new FileReader("words2.txt");
BufferedReader br = new BufferedReader(reader);

String s = null;
while ((s = br.readLine()) != null) {
list.add(s);
}
br.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}

public String getMoreThanHalf(LinkedList<String> list)
{
int len=list.size();
int mid=len/2;
int start=0;
int end=len-1;
int index=partition(list,len,start,end);
while(index!=mid)//index总会等于mid的
{
if(index>mid)
{
end=index-1;
index=partition(list,len,start,end);
}
else
{
start=index+1;
index=partition(list,len,start,end);
}
}
//到这里index=mid
return list.get(index);
}

public int partition(LinkedList<String> list,int len,int start,int end)
{
String s=list.get(start);
while(start<end)
{
//找出第一个
while(start<end&&s.compareTo(list.get(end))<=0)
end--;
list.set(start, list.get(end));
while(start<end&&s.compareTo(list.get(start))>=0)
start++;
list.set(end, list.get(start));
}
list.set(start, s);
return start;
}

// 打印LinkedList中的值
//方法1
public void printLinkedList(LinkedList<String> list) {
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
//方法2
public void printLinkedList2(LinkedList<String> list) {
for(int i=0;i<list.size();i++)
{
System.out.println(list.get(i));
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: