更多2019年的技術文章,歡迎關注我的微信公衆號:碼不停蹄的小鼠松(微信號:busy_squirrel),也可掃下方二維碼關注獲取最新文章哦~
T:
題目描述
在一個字符串(1<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符的位置。若爲空串,返回-1。位置索引從0開始.
這道題目,和以下問題的解決思路類似:
問題:
給定一個字符串,該字符串都是由阿拉伯數字0~9組成,該字符串可能很長(幾萬,甚至更長),問如何更快的找出所有隻出現過一次的數字?
解法相同,而設定場景不同,這就是需要融會貫通的地方。
-
比較笨的一種解法,那就是用一個兩層循環來做,看看當前位置的元素是否在後面也出現過。該解法的時間複雜度爲,當很大的時候,那是相當的不能忍啊。。。
-
還一種相對容易一些的方法,就是先遍歷一遍,統計各個元素出現的次數,再在統計數據中找出數值爲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),也可掃下方二維碼關注獲取最新文章哦~