題目:實現(xiàn)一個算法,確定一個字符串 s 的所有字符是否全都不同。
示例1:
輸入: s = "leetcode"
輸出: false
示例2:
輸入: s = "abc"
輸出: true
解決方法:
- 暴力解決(雙重循環(huán))
- Set(ES6新增)
- 散列思想
- 位運算
具體實現(xiàn):
1.暴力解決(雙重循環(huán))
略
2.Set
ES6 提供了新的數(shù)據(jù)結(jié)構 Set。它類似于數(shù)組,但是成員的值都是唯一的,沒有重復的值。Set 本身是一個構造函數(shù),用來生成 Set 數(shù)據(jù)結(jié)構。
思路:比較去重后的字符串長度和初始字符串的長度是否相等
代碼實現(xiàn):
function isUnique(astr) {
return new Set(astr).size === astr.length
}
注解:Set數(shù)組去重:
const arr = ['a', 'b', 'c', 'b', 'd', 'a']
// 方法一:...將一個數(shù)組轉(zhuǎn)為用逗號分隔的參數(shù)序列
const unique = [...new Set(arr)] // ['a','b','c','d']
// 方法二:Array.from 方法可以將 Set 結(jié)構轉(zhuǎn)為數(shù)組
const unique = Array.from(new Set(arr)) // ['a','b','c','d']
3.散列思想
思路:定義一個對象用來存儲當前遍歷的值,若值存在則說明有重復,返回false,沒有則把當前值置1。
代碼實現(xiàn):
function isUnique(astr) {
let obj = {}
for (let i of astr) {
if (obj[i]) {
return false
} else {
obj[i] = 1
}
}
return true
}
4.位運算
思路:假設有一個全為0的數(shù)mark:000000…000,共26位,每一位代表一個字母
0 0 0 0 0 0 0 … 0 0 0
↓
z y x w v u t… c b a
當前位置為0,代表沒出現(xiàn)過這個字母;如果為1,代表出現(xiàn)過這個字母。
// 每一個位置代表一個字母,如:
000000...0001 代表有字母a,沒有其它字母
000000...0011 代表有字母a和b,沒有其它字母
100000...0111 代表有字母a、b、c和z,沒有其他字母
當我們遍歷字符串'abcbda'時,如果之前沒出現(xiàn)過當前字符,則把00000...0000對應位置設置為1,出現(xiàn)過返回false
實現(xiàn)步驟:
1.遍歷把字符串中每個字符轉(zhuǎn)化為一個二進制數(shù)
2.計算這個字符距離'a'即97('a'.charCodeAt() = 97)的距離,這個距離代表我們要位移的距離,用move_bit表示
例如:
char = 'a', 和'a'的距離為0, 位移0位
char = 'b', 和'a'的距離為1, 位移1位
3.再使用左移運算符 1 << move_bit
例如:
char = 'a', 位移0位,1 << 0,得到 000000...0001
char = 'b', 位移1位,1 << 1,得到 000000...0010
4.做與運算,比如:'a':000000...0001與'b':000000...0010結(jié)果為0;若有重復,比如'a':000000...0001與'a':a000000...0001結(jié)果為1,返回false
代碼實現(xiàn):
function isUnique(astr) {
var mark = 0
for(var char of astr) {
var move_bit = char.charCodeAt() - 97
if ((mark & (1 << move_bit)) !== 0) {
return false
}
mark = mark | (1 << move_bit)
}
return true
}
參考:
作者:h-jia-jun
鏈接:https://leetcode-cn.com/problems/is-unique-lcci/solution/yi-ti-duo-jie-by-h-jia-jun-kw69/
來源:力扣(LeetCode)
著作權歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權,非商業(yè)轉(zhuǎn)載請注明出處。