码迷,mamicode.com
首页 > 其他好文 > 详细

找出数组中出现次数超过一半的数字

时间:2014-09-23 21:21:55      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:style   java   ar   for   sp   on   c   log   时间   

题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。

解法1:将数组利用快速排序进行排序,因为数组中有一个数字出现的次数超过了数组长度的一半,则排序以后直接取得最中间的那个数字即可!

时间复杂度为:o(n*logN),因为时间主要花费在快速排序上面了!

public static int find1(int[] a) {

		Arrays.sort(a);
		int mid = 0 + (a.length - 0) / 2;
		int result = a[mid];
		return result;
	}

解法2:我们可以创建一个哈希表来消除排序的时间。哈希表的键值(Key)为数组中的数字,值(Value)为该数字对应的次数。有了这个辅助的哈希表之后,我们只需要遍历数组中的每个数字,找到它在哈希表中对应的位置并增加它出现的次数。这种哈希表的方法在数组的所有数字都在一个比较窄的范围内的时候很有效。

// 根据hash表来计算,将其中的key为数字,值为key出现的次数

	public static int find2(int[] a) {

		Map<Integer, Integer> map = new HashMap<>();
		map.put(a[0], 1);

		for (int i = 1; i < a.length; i++) {

			if (map.containsKey(a[i])) {
				map.put(a[i], map.get(a[i]) + 1);

			} else {
				map.put(a[i], 1);
			}
		}

		Set<Integer> set = map.keySet();
		Iterator<Integer> iterator = set.iterator();
		int max = -1;
		int index = -1;
		while (iterator.hasNext()) {
			int key = (int) iterator.next();
			int value = map.get(key);
			if (value > max) {
				max = value;
				index = key;
			}

		}
		return index;

	}

3:

前面两种思路都没有考虑到题目中数组的特性:数组中有个数字出现的次数超过了数组长度的一半。也就是说,有个数字出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1。如果下一个数字和我们之前保存的数字不同,则次数减1。如果次数为零,我们需要保存下一个数字,并把次数设为1。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字。

public static int find3(int[] a) {

		// 初始化出现在爱第一个数字,并将第一个数字出现的次数设置为1;
		int count = 1;
		int number = a[0];
		for (int i = 1; i < a.length; i++) {
			if (a[i] == number) {
				count++;
			} else {
				count--;
			}
			if (count == 0) {

				number = a[i];
				count = 1;

			}

		}

		return number;

	}




找出数组中出现次数超过一半的数字

标签:style   java   ar   for   sp   on   c   log   时间   

原文地址:http://blog.csdn.net/shiyeqiangldh/article/details/39500225

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!