面试题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 Codeimport 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)); } } }
相关文章推荐
- P163、面试题29:数组中出现次数超过一半的数字
- 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)
- 面试题29:数组中出现次数超过一半的数字
- 剑指offer 面试题29 数组中出现次数超过一半的数字
- 数组中出现次数超过一半的数字(面试题 29)
- 剑指Offer:面试题29 数组中出现次数超过一半的数字
- 面试题29:数组中出现次数超过一半的数字
- 面试题29:找到数组中出现次数超过一半的数字(java)
- 面试题29:数组中出现次数超过一半的数字
- 面试题29—数组中出现次数超过一半的数字
- 剑指offer面试题29:数组中出现次数超过一半的数字
- 面试题29:数组中出现次数超过一半的数字
- 面试题29 数组中出现次数超过一半的数字
- 算法题005 剑指Offer面试题29 数组中出现次数超过一半的数字
- 【剑指Offer】面试题29:数组中出现次数超过一半的数字
- 面试题29. 数组中出现次数超过一半的数字
- 面试题29:数组中出现次数超过一半的数字
- 剑指Offer----面试题29:数组中出现次数超过一半的数字
- 剑指offer--面试题29:数组中出现次数超过一半的数字
- 剑指offer-----面试题29(数组中出现次数超过一半的数字)