详解isUnique函数中lastIndexOf检测重复字符的工作原理
lastIndexOf 方法的基础工作规则 JavaScript 字符串的lastIndexOf()方法在不传第二个位置参数时,会从字符串的最末尾开始反向查找目标字符,最终返回该字符在整个字符串中最后一次出现的索引值;如果字符串里完全不存在目标字符,就返回-1。
举个简单例子:对于字符串abcaef,'abcaef'.lastIndexOf('a')会返回3,因为字符a最后一次出现在索引3的位置;'abcaef'.lastIndexOf('b')返回1,因为b只出现过一次,最后一次出现的位置就是它本身的位置。
重复字符判断逻辑的原理
题目中的完整实现代码如下:
// 测试用例 isUnique('abcdef'); // 全唯一字符,应返回true isUnique('89%df#$^a&');// 全唯一字符,应返回true isUnique('abcaef'); // a重复,应返回false function isUnique(str) { for(var i = 0; i < str.length; i++) { if(str.lastIndexOf(str[i]) !== i) return false; } return true; }
判断逻辑的核心非常直白:
- 循环里的
i是当前遍历位置的索引,对应str[i]是当前正检查的字符 - 如果一个字符在整个字符串里只出现一次,那它「最后一次出现的位置」必然就是当前的
i,两者一定相等 - 只要字符存在重复,那它的最后一次出现位置,一定比它靠前的重复位置的索引大。当遍历到靠前位置的这个重复字符时,
lastIndexOf返回的是后面那个重复项的索引,和当前i不相等,就会直接命中判断返回false,说明存在重复字符。
拿反例abcaef走一遍流程就很清楚:
- i=0时,当前字符是
a,str.lastIndexOf('a')返回3,3 !== 0,直接判定存在重复,返回false,不需要继续往后遍历。 - 如果是全唯一的字符串比如
abcdef,每个字符的最后一次出现位置都和当前遍历的i完全相等,循环走完都不会命中判断,最终返回true。
注:这个写法不需要额外开辟内存存储已出现的字符,属于入门阶段很取巧的实现,但时间复杂度是O(n²)——因为每次调用
lastIndexOf内部都会遍历一次字符串,字符串长度较大时效率偏低。
内容的提问来源于stack exchange,提问作者Max Chergik
相关产品推荐
相关产品推荐

