LeetCode.jpg
題目:字符串中的第一個唯一字符
描述:
給定一個字符串惜颇,找到它的第一個不重復的字符,并返回它的索引恤筛。如果不存在官还,則返回 -1。
案例:
s = "leetcode"
返回 0.
s = "loveleetcode",
返回 2.
一毒坛、可以參照Swift 存在重復 - LeetCode中的哈希表解決方案望伦,記錄字符串出現(xiàn)的索引位置
1林说、將字符串轉(zhuǎn)為數(shù)組
2、循環(huán)字符串數(shù)組屯伞,將字符作為鍵腿箩,索引作為值存入字典
3、存入字典時先判斷是否已經(jīng)存在劣摇,已存在則將值置位-1
4珠移、循環(huán)字典,拿到所有的值
5末融、將值排序(因為都是整數(shù))钧惧,最小值即為所求的索引
class Solution {
func firstUniqChar(_ s: String) -> Int {
var charArr = [String]()
for character in s { //將字符串轉(zhuǎn)為數(shù)組
charArr.append(String(character))
}
var dic = [String: Int]()
for i in 0..<charArr.count {
if let _ = dic[charArr[i]] { //當字典內(nèi)已經(jīng)存在該字符,此時直接將其置為-1
dic[charArr[i]] = -1
} else {
dic[charArr[i]] = i //記錄字符出現(xiàn)的索引位置
}
}
var newArray = [Int]()
//循環(huán)字典勾习,拿到所有的值
for (_, value) in dic {
if value != -1 { //將所有補位-1的索引添加到新的數(shù)組中
newArray.append(value)
}
}
// 如果數(shù)組不為空浓瞪,則取最小值,即第一次出現(xiàn)的索引巧婶,所以排序后取第一個值
if newArray.count > 0 {
return newArray.sorted().first!
}
return -1
}
}
但是分析一下算法乾颁。。艺栈。循環(huán)很多英岭,需要創(chuàng)建的輔助變量也很多,同時還要排序湿右,但是個人以為最重要的原因可能是Character轉(zhuǎn)換String耗時較多(ps:求大神解答)诅妹,并且運行效率確實不高,在LeetCode中只戰(zhàn)勝了20%的方案(執(zhí)行用時1016ms)诅需、漾唉、、堰塌、
二赵刑、使用Unicode標量參,考官方網(wǎng)String and Characters
我們可以使用String類型的unicodeScalars屬性遍歷一個Unicode標量編碼的字符串。這個屬性是 UnicodeScalarsView類型场刑,UnicodeScalarsView是一個UnicodeScalar類型的集合般此。每一個Unicode標 量都是一個任意21位Unicode碼位,沒有高位代理牵现,也沒有低位代理铐懊。
每一個UnicodeScalar使用value屬性,返回標量的21位值瞎疼,每一位都是32位無符號整形(UInt32)的值:
參考官方例子:
let dogString = "Dog???"
for scalar in dogString.unicodeScalars {
print("\(scalar.value) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 128054 "
for scalar in dogString.unicodeScalars {
print("\(scalar) ")
}
// D
// o
// g
// ?
// ??
我們知道我們小寫字母的ASCII碼值A是從97開始的科乎,所以:
1、先創(chuàng)建一個包含26個0作為值的數(shù)組
2贼急、循環(huán)string的unicodeScalars獲取其value
3茅茂、將value - 97 代表字符捏萍,記錄該字符出現(xiàn)的次數(shù)
4、再次循環(huán)string空闲,獲取第一個出現(xiàn)次數(shù)為1的字符
代碼如下:
func firstUniqChar(_ s: String) -> Int {
//創(chuàng)建一個含有26個為0的值的數(shù)組
var array = Array<Int>(repeating: 0, count: 26)
for character in s.unicodeScalars {
let index = Int(character.value - 97)
//記錄字符出現(xiàn)的次數(shù)
array[index] = array[index] + 1
}
//再次循環(huán)string令杈,使用enumerated()獲取到字符串的索引
for (index, character) in s.unicodeScalars.enumerated() {
let count = array[Int(character.value - 97)]
if count == 1 {
return index
}
}
return -1
}
可以看到運行結果如下:
執(zhí)行用時:172ms
運行結果.png