1. 程式人生 > >劍指Offer-第一個只出現一次的字元(Java實現)

劍指Offer-第一個只出現一次的字元(Java實現)

題目描述:

在一個字串(0<=字串長度<=10000,全部由字母組成)中找到第一個只出現一次的字元,並返回它的位置, 如果沒有則返回-1(需要區分大小寫).

思路分析:
方法一:
個人思路
比較粗暴,將字串轉換成字元陣列,按順序遍歷字元陣列。需要兩個指標,指標1指向首次出現的字元,指標2從指標1的位置往後遍歷,找出與指標1相同的字元。
1,新建一個HashSet集合,用於儲存已經重複出現的字元;
2,先判斷指標位置上的元素是否包含在重複字元的集合中,如果重複指標1直接跳到下一個位置。繼續2過程。
3,若元素沒有包含在Set集合中,則指標2從指標1位置依次往後遍歷,判斷是否有相同的字元出現,若有相同的元素出現,則將該元素存入Set集合中,指標1指向下一個元素。繼續用2過程。
4,若指標2到達字元陣列末尾時還未發現重複字元,則直接返回指標1位置的字元即可。
5,若遍歷完整個陣列都沒找出出現一次的字元,則返回-1;

程式碼實現如下:

import java.util.HashSet;
public class Solution {
    public int FirstNotRepeatingChar(String str) {
        if(str == null || str.length()< 1){
            return -1;
        }
        char[] ch = str.toCharArray();
        HashSet<Character> set = new HashSet<Character>();
        for(int i = 0 ; i < str.length()-1; i++){
            for(int j = i+1 ; j < ch.length;j++){
                if(set.contains(ch[i])){
                    break;
                }
                if(ch[i]==ch[j]){
                    set.add(ch[i]);
                    break;
                }
                if(j==ch.length-1){
                    return i;
                }
            }
        }
        return -1;
    }
}

方法2:
參考牛客網上大佬的思路:
連結:https://www.nowcoder.com/questionTerminal/1c82e8cf713b4bbeb2a5b31cf5b0417c
來源:牛客網
說一下解題思路哈,其實主要還是hash,利用每個字母的ASCII碼作hash來作為陣列的index。首先用一個58長度的陣列來儲存每個字母出現的次數,為什麼是58呢,主要是由於A-Z對應的ASCII碼為65-90,a-z對應的ASCII碼值為97-122,而每個字母的index=int(word)-65,比如g=103-65=38,而陣列中具體記錄的內容是該字母出現的次數,最終遍歷一遍字串,找出第一個陣列內容為1的字母就可以了,時間複雜度為O(n)

程式碼實現如下:

public class Solution {
    public int FirstNotRepeatingChar(String str) {
         int[] words = new int[58];
         for(int i = 0;i<str.length();i++){
            words[((int)str.charAt(i))-65] += 1;
         }
         for(int i=0;i<str.length();i++){
             if(words[((int)str.charAt(i))-65]==1)
                  return i;
         }
         return -1;
    }
}