1. 程式人生 > 其它 >劍指 offer程式碼解析——面試題35第一個只出現一次的字元

劍指 offer程式碼解析——面試題35第一個只出現一次的字元

本題的詳細解析均在程式碼註釋中:

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * 題目:在字元陣列中找出第一個只出現一次的字元。
 * @author 大閒人柴毛毛
 * @date 2016年3月24日
 */
public class FirstChar {
	/**
	 * 分析:本題最直觀的思路是從頭到尾掃描陣列,假設當前掃描的字元為a[i],
	 * 若尚未統計a[i]出現的次數的話,則從a[i]開始,向後統計a[i]出現的次數。
	 * 這種方式需要掃描陣列n次,且每次還需要進行n次掃描統計a[i]出現的次數,因此時間複雜度為O(n^2)。
	 * 是否有更高效的方法呢?
	 */
	
	
	/**
	 * 要想降低時間複雜度,我們就應該想到“用空間換取時間”的思想。
	 * 如果我們只對陣列掃描一遍,那麼需要額外的空間來儲存每個字元在陣列中出現的個數。
	 * 這個資料結構能支援通過字元來獲取該字元出現的次數。在Java中,Map能儲存任意型別的鍵值對,因此適合本題。
	 * 程式碼如下:
	 */
	
	/**
	 * 獲取字元陣列中第一個只出現一次的字元
	 * @param a 字元陣列
	 * @return 返回第一個只出現一次的字元
	 */
	private static boolean result = true;
	public static char getFirstChar(char[] a){
		
		//若陣列為空
		if(a==null || a.length<=0){
			System.out.println("字元陣列為空!");
			result = false;
			return ' ';
		}
		
		//建立Map,用於儲存“字元”-“該字元出現的次數”
		Map<Character,Integer> map = new LinkedHashMap<Character,Integer>();
		
		//掃描陣列,統計每個字元出現的次數
		for(int i=0;i<a.length;i++){
			//獲取字元a[i]到目前為止出現的次數
			int count; 
			if(map.get(a[i])==null) 
				count = 0;
			else
				count = map.get(a[i]);
			
			//將次數+1存入map
			map.put(a[i], ++count);
		}
		
		//遍歷map,取出第一個個數為1的字元
		Set<Character> keys = map.keySet();
		for(char key : keys){
			if(map.get(key)==1)
				return key;
		}
		
		return ' ';
	}
	
	
	
	/**
	 * 測試
	 */
	public static void main(String[] args){
		char[] a = {'a','b','a','c','c','d','e','f','b'};
		System.out.println(getFirstChar(a));
	}
}