剑指Offer面试题(第二十四天)面试题39(Partition)、39(ArrayFeature)

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


     * 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
     * 例如:输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.
     * 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2
     * 
     * 思路:Partition方法
     * 将数组进行排序,若是某个数字在数组中超过一半,
     *那么排序后的中间位置的数字就是要找的那个重复的数字
     *使用快速排序的方法,将其进行排序  找到中间的,
     *并且使用一个函数再对该数字进行检验,查看重复量是否超过了一半
 

package Test;

public class No39MoreThanHalfNum {

	/*
	 * 面试题39:数组中出现次数超过一半的数字
	 * 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
	 * 例如:输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.
	 * 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2
	 * 
	 * 
	 * 思路:Partition方法
	 * 将数组进行排序,若是某个数字在数组中超过一半,
	 *那么排序后的中间位置的数字就是要找的那个重复的数字
	 *使用快速排序的方法,将其进行排序  找到中间的,
	 *并且使用一个函数再对该数字进行检验,查看重复量是否超过了一半
	 * 
	 * */
	//int flag = 0;
	//标志位(当number=0时)  :若flag为0  表示数组不为空   若flag为1  表示数组为空 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		No39MoreThanHalfNum m = new No39MoreThanHalfNum();
		
		int[] array = {1,2,3,2,2,2,5,4,2};
		
		System.out.println("数组中超过一半的数字是:"+m.MoreThanHalfNum_Solution(array));
	
	}

	//查找数组中超过一半的数字
	public int MoreThanHalfNum_Solution(int[] array) {
		// TODO Auto-generated method stub
		
		if(array == null || array.length == 0) {
//			flag = 1;
			return 0;
		}
		int midIndex = array.length/2;
		int low = 0;
		int high = array.length - 1;
		int p = partition(array,low,high);
		//若是p !中间值,则继续找中间值
		while(p != midIndex) {
			
			if(p > midIndex)
				high = p - 1;
			else if(p < midIndex)
				low = p + 1;
			p = partition(array,low,high);
		}
		
		if(checkMoreThanHalf(array,array[p])) 
			return array[p];
		return 0;
	}

	
	//判断是否中间值array[p]  在数组中出现的次数超过了一半
	public boolean checkMoreThanHalf(int[] array, int val) {
		// TODO Auto-generated method stub
		System.out.println(val);
		int count = 0;
		for(int i = 0;i < array.length;i++) {
		//for(int i : array)
			//if(i == val)
			if(array[i] == val)
				count++;
		}
		//若count大于数组长度一半,则返回true;否则返回false
		return count > array.length/2;
	}

	//快速排序算法   然后索引号
	public int partition(int[] array,int low,int high) {
		
		int val = array[low];
		int i = low + 1;
		int j = high;
		//走一遍 从左到右  右边小  左边大
		while(i <= j) {
			while(i <= high && array[i] < val)
				i++;
			while(j >= low && array[j] > val)
				j--;
			if(i > j) 
				break;
			//找到左边大的  和  右边小的 
			//首先进行交换
			//然后i自加,j自加向下继续比较
			swap(array,i++,j--);
				
		}
		//将选定的节点,与j进行交换   形成  左边小   右边大的数组
		swap(array,low,j);
		return j;
	}
	
	public void swap(int[] array,int indexA,int indexB) {
		int temp = array[indexA];
		array[indexA] = array[indexB];
		array[indexB] = temp;
	}
}

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


     * 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
     * 例如:输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.
     * 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2
     * 
     * 
     * 思路:根据数组特点找出时间复杂度为O(n)的算法
     * 定义两个变量:一个用于记录数字  一个用于记录数字出现的次数
     * 首次访问该数字时,次数设置为1,访问之后的元素,相等,则加1;不等,则减1;
     * 若次数等于零,则开始记录下一个数字
     * 其中因为重复超过数组的一半,所以该数字应该是最后一个次数被设置为1的值   
 

package Test;

public class No39MoreThanHalfNum_ArrayFeature {

	/*
	 * 面试题39:数组中出现次数超过一半的数字
	 * 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
	 * 例如:输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.
	 * 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2
	 * 
	 * 
	 * 思路:根据数组特点找出时间复杂度为O(n)的算法
	 * 定义两个变量:一个用于记录数字  一个用于记录数字出现的次数
	 * 首次访问该数字时,次数设置为1,访问之后的元素,相等,则加1;不等,则减1;
	 * 若次数等于零,则开始记录下一个数字
	 * 其中因为重复超过数组的一半,所以该数字应该是最后一个次数被设置为1的值   
	 * 
	 *  
	 *  
	 * */
	//int flag = 0;
	//标志位(当number=0时)  :若flag为0  表示数组不为空   若flag为1  表示数组为空 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		No39MoreThanHalfNum_ArrayFeature m = new No39MoreThanHalfNum_ArrayFeature();
		
		int[] array = {1,2,3,2,2,2,5,4,2};
		
		System.out.println("数组中超过一半的数字是:"+m.MoreThanHalfNum_Solution(array));
	
	}

	//查找数组中超过一半的数字
	public int MoreThanHalfNum_Solution(int[] array) {
		// TODO Auto-generated method stub
		
		if(array == null || array.length == 0) {
//			flag = 1;
			return 0;
		}
		//从数组的第一个数字开始遍历
		//记录数值
		int result = array[0];
		//记录次数
		int times = 1;
		for(int i = 1;i < array.length;i++) {
			//若次数为0  需要保存下一个数字  并且设置times为1
			if(times == 0) {
				result = array[i];
				times = 1;
			}
			//若当前值和记录的值相等  则 times加1
			else if(array[i] == result) {
				times ++;
			}
			//若当前值和记录的值不相等  则 times减1
			else {
				times --;
			}
		}
		
		if(checkMoreThanHalf(array,result)) 
			return result;
		return 0;
	}

	
	//判断是否中间值array[p]  在数组中出现的次数超过了一半
	public boolean checkMoreThanHalf(int[] array, int val) {
		// TODO Auto-generated method stub
		System.out.println(val);
		int count = 0;
		for(int i = 0;i < array.length;i++) {
		//for(int i : array)
			//if(i == val)
			if(array[i] == val)
				count++;
		}
		//若count大于数组长度一半,则返回true;否则返回false
		return count > array.length/2;
	}

	
	
}

 

你可能感兴趣的:(面试)