LeetCode #387 First Unique Character in a String 字串中第一個唯一的字元

英文原文如下

Given a string sfind the first non-repeating character in it and return its index. If it does not exist, return -1.

中文翻譯

給予一個字串 s,找到第一個不重複的字元並回傳其索引,如果不存在則回傳 -1

範例及題目限制


解題思路

C# 解決方案

方案1 – Dictionary & HashSet

public class Solution {
    public int FirstUniqChar(string s) {
        Dictionary<char,int> dict =   new Dictionary<char,int>();
        HashSet<char> hSet = new HashSet<char>();
        
        for(int i = 0; i<s.Length;i++)
        {
            char c = s[i];
            
            if(hSet.Contains(c))
            {
                continue;
            }
                
            
            if (!dict.ContainsKey(c))
            {
                dict.Add(c, i);
            }
            else
            {
                dict.Remove(c);
                hSet.Add(c);
            }
        }
        
        if(dict.Count == 0)
        {
            return -1;
        }
        
         return dict.MinBy(k => k.Value).Value;
    }
}

在第一個解法中,我們使用dictionary來儲存字元跟索引 ➡ 如果遇到第二次就會將其移除

HashSet 則用來記錄已經處理過的字元 ➡ 出現過兩次以上的 ➡ 以後遇到就跳過

時間複雜度 : O(n)

方案2 – ascii code 搭配 indexOf

public class Solution {
    public int FirstUniqChar(string s) {
        
        int min = Int32.MaxValue;
        
        for (char c = 'a'; c <= 'z'; c++)
        {
            int tmp = s.IndexOf(c);
            if(tmp!=-1 && tmp == s.LastIndexOf(c))
            {
                min = tmp<min ? tmp : min;
            }
        } 
        min = min == Int32.MaxValue ? -1 : min;
            
        return min;
    }
}

第二個解決方法中直接使用ascii code來判斷

ascii code進行的是遞迴的判斷 (a 到 z)

另外搭配 indexOf 跟 lastIndexOf ,要是出現的索引相等就代表該字元僅出現一次

時間複雜度 : O(n) ➡ 但理論上比解法1來的更快,省略了dict跟hashmap的判斷,而且總運行次數固定為26次(英文字母的總數)

Java解決方案

方案1

class Solution {
    public int firstUniqChar(String s) {
        Map<Character, Integer> dict = new HashMap<Character, Integer>();
        HashSet<Character> hSet  = new HashSet<Character>();
        
        for(int i = 0; i<s.length();i++)
        {
            char c = s.charAt(i);
            
            if(hSet.contains(c))
            {
                continue;
            } 
            
            if (!dict.containsKey(c))
            {
                dict.put(c, i);
            }
            else
            {
                dict.remove(c);
                hSet.add(c);
            }
        }
        
        if(dict.size() == 0)
        {
            return -1;
        }
        
        int min = Integer.MAX_VALUE;
        
        for (Integer value : dict.values()) {
            min = value<min ? value : min;
        }
        
        return min;
    }
}

方案2

class Solution {
    public int firstUniqChar(String s) {
        int min = Integer.MAX_VALUE;
        
        for (char c = 'a'; c <= 'z'; c++)
        {
            int tmp = s.indexOf(c);
            if(tmp!=-1 && tmp == s.lastIndexOf(c))
            {
                min = tmp<min ? tmp : min;
            }
        } 
        min = min == Integer.MAX_VALUE ? -1 : min;
            
        return min;
    }
}

Python3 解決方案

方案1

from string import ascii_lowercase as alc

class Solution:
    def firstUniqChar(self, s: str) -> int:
        
        m = math.pow(10,5);     #min
        
        for c in alc:
            try:
                tmp = s.index(c)
                tmp2 = s.rindex(c)
            except: 
                continue;
                
            if tmp == tmp2:
                m = tmp if tmp<m else m
                
        return -1 if m == math.pow(10,5) else m

JavaScript 解決方案

方案1

/**
 * @param {string} s
 * @return {number}
 */
var firstUniqChar = function(s) {
    var min = 10**5;
    for (var i = 97; i <= 122; i++) {
        var c = String.fromCharCode(i);
        
        var tmp = s.indexOf(c);
        if(tmp!=-1 && tmp == s.lastIndexOf(c))
        {
            min = tmp<min ? tmp : min;
        }
    }
    
    min = min == 10**5 ? -1 : min;
    return min;
};

結論

ascii code 不僅是一種常見的編碼格式,更在解決與字串字元相關的問題時非常有用

是需要學習如何好好利用的

🧡如果這篇文章有幫上你的一點點忙,那是我的榮幸

🧡收藏文章或幫我分享,我都會很感謝的

✅如有任何疑問,歡迎透過留言或messenger讓我知道 !

題目連結 : First Unique Character in a String – LeetCode

一些隨機文章

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *