面试题三十九:寻找数组中出现超过一半的数字
方法一:类似快速排序的方法将比选择打的数放在右边,选择小的数放在左边,如果下标为n/2,那么该值就是要找的数,如果大于n/2,那么中位数在左边,如果小于,那么在右边。
//目的,寻找数组中间位置该有的值 int MoreThanHalfNUm( int [ ] Array ){ if(Array==null) return 0; int middle=Array.length>>1; int start=0; int end=Array.length-1; int index=Patition(Array ,start ,end); //不求排序,只求不断向中间靠近 while(index!=middle){ if(index>middle){ end=index-1; } else start=index+1; index=Patition(Array ,start ,end); } int result=Array[middle]; //验证是否正确,如果该数不存在,那么中间这个值也不是 int count=0; for(int i=0;i<Array.length;i++) if(Array[i] == result) count++; if( (count<<1)>Array.length) return result; else return 0; } int Patition( int [] a,int be,int end){ int inter=a[be];//把起始位置作为主元 int L=be+1; int R=end; int b; while(L<=R)///数组都遍历完了即R与L交错时停止循环 { while(L<=R&&inter>=a[L]) L++; while(L<=R&&inter<a[R]) R--; if(L<R) {b=a[L]; a[L]=a[R]; a[R]=b;} ///交换位置,把比主元大的放后面 ,比主元小的放前面 } a[be]=a[R];a[R]=inter;///交换位置把主元放进去作为间隔 return R; }
方法二:根据数组特点,进行抵消法,设置两个变量,一个为数组中的数字,一个表示次数,因为数目超过数组一半,把数组中两个不相同数抵消,剩下的就是要寻找的值
int MoreThanHalfNum( int [] Array ){ if(Array==null) return 0; int result= Array[0]; int X=1; for(int i=1;i<Array.length;i++){ //表示抵消完 if(X==0){ result =Array[ i ]; X=1; } // 遇见相同的; else if(Array[ i ] == result) X++; else X--; } //验证是否正确,如果该数不存在,那么中间这个值也不是 int count=0; for(int i=0;i<Array.length;i++) if(Array[i] == result) count++; if( (count<<1)>Array.length) return result; else return 0; }
浪波激泥