1. 程式人生 > >陣列中出現次數超過一半的數字(劍指offer第29題)

陣列中出現次數超過一半的數字(劍指offer第29題)

一、題目描述

陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。
例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,
超過陣列長度的一半,因此輸出2。如果不存在則輸出0

二、解題思路

(方法一):自己想出來的,時間複雜度是O(N),但是空間複雜度也是O(N),不推存。

利用hashmap的k來存放陣列中的每一個元素,重複的元素則將v+1,找出map中的v為最大值的與陣列長度一半比較,超過則返回改K,否則返回0

(方法二):利用快速排序,找出中間的數,在求這個數的出現次數和陣列長度一般作比較。時間複雜度是O(nlogn),不推薦。

(方法三):推薦。時間複雜度是O(N),空間複雜度是O(1)。

     採用陣地攻守的思想: 第一個數字作為第一個士兵,守陣地;count = 1; 遇到相同元素,count++;
     遇到不相同元素,即為敵人,同歸於盡,count--;當遇到count為0的情況,又以新的i值作為守陣地的士兵,繼續下去,到最後還留在陣地上的士兵,有可能是主元素。
      再加一次迴圈,記錄這個士兵的個數看是否大於陣列一般即可。

三、java程式碼(只有第一種方法和第三種方法)

public class Solution_29 {
	/**
	 * 陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。
	 * 例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次
	 * ,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。
	 */

	// 方法一
	public int MoreThanHalfNum_Solution(int[] array) {
		// 思路:利用hashmap的k來存放陣列中的每一個元素,重複的元素則將v+1,找出map中的v為最大值的與陣列長度一半比較,超過則返回改K,
		// 否則返回0

		if (array == null || array.length == 0) {
			return 0;
		}
		if (array.length == 1) {
			return array[0];
		}
		int result = 0;
		HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();

		for (int i = 0; i < array.length; i++) {
			if (map.containsKey(array[i])) {
				map.put(array[i], map.get(array[i]) + 1);
			} else {
				map.put(array[i], 1);
			}
		}

		Set<Entry<Integer, Integer>> set = map.entrySet();
		Iterator<Entry<Integer, Integer>> iterator = set.iterator();
		while (iterator.hasNext()) {
			Entry<Integer, Integer> entry = iterator.next();
			// System.out.println(entry.getKey()+"-->"+entry.getValue());
			if (entry.getValue() > (array.length / 2)) {
				return entry.getKey();
			}
		}
		return result;
	}

	// 方法二
	/**
	 * 思路: 採用陣地攻守的思想: 第一個數字作為第一個士兵,守陣地;count = 1; 遇到相同元素,count++;
	 * 遇到不相同元素,即為敵人,同歸於盡
	 * ,count--;當遇到count為0的情況,又以新的i值作為守陣地的士兵,繼續下去,到最後還留在陣地上的士兵,有可能是主元素。
	 * 再加一次迴圈,記錄這個士兵的個數看是否大於陣列一般即可。
	 */
	public int MoreThanHalfNum_Solution1(int[] array) {
		int length = array.length;
		if (array == null || length <= 0) {
			return 0;
		}

		int result = array[0];
		int times = 1;
		for (int i = 1; i < length; i++) {
			if (times == 0) {
				result = array[i];
				times = 1;
			} else {
				if (array[i] == result) {
					times++;
				} else {
					times--;
				}
			}
		}

		times = 0;
		for (int i = 0; i < length; i++) {
			if (result == array[i]) {
				times++;
			}
		}

		if (times * 2 < length) {
			result = 0;
		}
		return result;
	}

	public static void main(String[] args) {
		int[] array = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
		Solution_29 s = new Solution_29();
		System.out.println(s.MoreThanHalfNum_Solution1(array));
	}
}