算法题
这是一道关于哈希表的题目,判断两个字符串的组成字母是否相同
基本解题思路
- 两个字符串的长度是否相等,不相等返回false
- 判断两个字符串的字符是否相等
解法一:基于 js 语言特性实现
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function(s, t) {
return s.length == t.length && [...s].sort().join('') === [...t].sort().join('')
};
解题思路
- 短路运算两个字符创的长度是否相等
- 通过字符串的遍历以及排序,生成排序后的字符串(方便后续比较)
- 通过数组相等的方式进行比较
- 优势
- 书写方便、快速
- 缺点
- 时间使用量大
- 内存使用量大
解法二:基于哈希表实现
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function(s, t) {
if(s.length !== t.length) return false
const table = new Array(26).fill(0)
for(let i = 0; i <= s.length; i++) {
table[s.codePointAt(i) - 'a'.codePointAt(0)]++
}
for(let i = 0; i <= t.length; i++) {
table[t.codePointAt(i) - 'a'.codePointAt()]--
if(table[t.codePointAt(i) - 'a'.codePointAt(0)] < 0) {
return false
}
}
return true
};
解题思路
- 判断两个字符串的长度是否相等
- 注册基于字母下标的数组
- 遍历 s 字符串,字母记录使用情况
- 遍历 t 字符串,减去字母的使用情况,当发现 t 中的某个字母 使用次数大于 s 中的使用次数时,返回false
- 如果前面的执行没有问题,返回 true
小记:是基于哈希表的基本实现,在内存使用方面还可以通过减少内存访问优化时间,如下:
解法三:优化性能
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function(s, t) {
if(s.length !== t.length) return false;
const resSet = new Array(26).fill(0);
const base = "a".charCodeAt();
for(const i of s) {
resSet[i.charCodeAt() - base]++;
}
for(const i of t) {
if(!resSet[i.charCodeAt() - base]) return false;
resSet[i.charCodeAt() - base]--;
}
return true;
};
面试题
var、let、const 定义变量有什么区别
在ES6之前,JavaScript 使用 var 定义变量,且作用域只有全局作用域和函数作用
var定义的变量存在三个特性
- 没有块级作用域的概念,可以跨块使用,不能跨函数使用
- 该变量会挂载到全局对象上
- 该变量存在变量提升
这些特性就会导致两个问题
- 在遍历的过程中,变量的值不会绑定当前的作用域
- 该变量可能会被外部的代码修改
ES6 出现了块级作用域,大大的保护了变量的安全,同时也推出了 let 和 const 来定义变量
let 和 const 的变量存在以下特性
- 定义的变量属于块级作用域,超过块级作用域会报错,变量的使用基于作用域链
- 变量不存在作用域提升,在声明之前使用变量会报错(暂时性死区)
- 已声明的变量不允许重复声明
区别:let 的变量可以修改地址,而const 的变量不能修改地址