《劍指offer》——第一個只出現一次的字符位置

更多2019年的技術文章,歡迎關注我的微信公衆號:碼不停蹄的小鼠松(微信號:busy_squirrel),也可掃下方二維碼關注獲取最新文章哦~

T:

題目描述
在一個字符串(1<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符的位置。若爲空串,返回-1。位置索引從0開始.

這道題目,和以下問題的解決思路類似:

問題:

給定一個字符串,該字符串都是由阿拉伯數字0~9組成,該字符串可能很長(幾萬,甚至更長),問如何更快的找出所有隻出現過一次的數字?

解法相同,而設定場景不同,這就是需要融會貫通的地方。

  • 比較笨的一種解法,那就是用一個兩層循環來做,看看當前位置的元素是否在後面也出現過。該解法的時間複雜度爲O(n2)O(n^2),當nn很大的時候,那是相當的不能忍啊。。。

  • 還一種相對容易一些的方法,就是先遍歷一遍,統計各個元素出現的次數,再在統計數據中找出數值爲1的元素。

那麼問題的關鍵就是在這個統計結構的設計了,如何設計?也許用一個二維數組,那麼,如果元素不是阿拉伯數字,而是字母怎麼辦?這是相對麻煩的一種,幸好java都已經做了封裝,我們可以用hashMap,或者hashSet來解決。

如果用c語言來實現,又該怎麼破?沒有封裝好的哈希來調用,只能尋求其他方法。如果是阿拉伯數字,那麼統計結構就可以設計成爲一個長度爲10的一維整型數組,字符串中出現的阿拉伯數字就可用來代表其在整型數組中的下標,問題迎刃而解,省時省力省空間。如果不是阿拉伯數字,而是字母,那就設定一個長度爲26的整型一維數組。

先給出一個hashMap版本的:

code:

	import java.util.HashMap;
	
	/**
	 * T: 第一個只出現一次的字符位置
	 * 
	 * 題目描述 
	 * 在一個字符串(1<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符的位置。
	 * 若爲空串,返回-1。位置索引從0開始.
	 * 
	 * date: 2015.11.17  21:16
	 * @author SSS
	 *
	 */
	public class Solution {
	    
	    /**
		 * 設立一個hashMap,將每個字母出現的次數進行統計。
		 * 若要找出第一個,就要對string從頭開始再次遍歷一遍,
		 * 找到其在hashMap中的value值爲1,則返回其下標
		 * @param str
		 * @return
		 */
	    public int FirstNotRepeatingChar(String str) {
			
	        int index = -1;
			if (str == null || str == "") {
				return index;
			}
	        
	        HashMap<Character, Integer> statisticsMap = new HashMap<Character, Integer>();
	        
	        // 第一次遍歷,統計每個字符出現的個數
	        for (int i = 0; i < str.length(); i++) {
				Character tempChar = str.charAt(i);
				if (statisticsMap.get(tempChar) == null) {
					statisticsMap.put(tempChar, 1);
				} else {
					int tempCount = statisticsMap.get(tempChar) + 1;
					statisticsMap.remove(tempChar);
					statisticsMap.put(tempChar, tempCount);
				}
			}
	        
	        // 第二次遍歷,找出第一個只出現一次的字符的下標位置
	        for (int i = 0; i < str.length(); i++) {
				Character tempChar1 = str.charAt(i);
				if (statisticsMap.get(tempChar1) == 1) {
					index = i;
					break;
				}
			}
	        
			return index;
	    }
	}

再來第二種用數組統計的方式:

code:

	import java.util.HashMap;
	
	/**
	 * T: 第一個只出現一次的字符位置
	 * 
	 * 題目描述 
	 * 在一個字符串(1<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符的位置。
	 * 若爲空串,返回-1。位置索引從0開始.
	 * 
	 * date: 2015.11.17  21:16
	 * @author SSS
	 *
	 */
	public class Solution {
	    
	    /**
		 * 另一種方式,用數組進行統計
		 * @param str
		 * @return
		 */
	    public int FirstNotRepeatingChar(String str) {
			int index = -1;
			if (str == null || str == "") {
				return index;
			}
			
			// 創建一個數組進行統計
			int []countArr = new int[26];
			// 初始化
			for (int i = 0; i < countArr.length; i++) {
				countArr[i] = 0;
			}
			
			// 本題目比較坑的地方,都是大寫或者都是小寫,先進行判斷
			char tempChar = 'a';
			if (str.charAt(0) < tempChar) {
				tempChar = 'A';
			}
			// 進行統計
			for (int i = 0; i < str.length(); i++) {
				int tempIndex = str.charAt(i) - tempChar;
				int nums = countArr[tempIndex];
				countArr[tempIndex] = nums + 1;
			}
			
			// 在原字符串中找出該字符第一次出現的地方,記錄其下標,中斷for循環
			for (int i = 0; i < str.length(); i++) {
				if (countArr[str.charAt(i) - tempChar] == 1) {
					index = i;
					break;
				}
			}
			
			return index;
	    }
	}

更多2019年的技術文章,歡迎關注我的微信公衆號:碼不停蹄的小鼠松(微信號:busy_squirrel),也可掃下方二維碼關注獲取最新文章哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章