今日练习题:(389)找不同
题目内容:给定两个字符串 s 和 t ,它们只包含小写字母。
字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。
请找出在 t 中被添加的字母。
练习语言:JavaScript
运行成功的自己的写法:67ms
var findTheDifference = function(s, t) {
// 字符串转换为数组
// let arrs = [...s]
// let [...arrs] = s
// let arrs = Array.from(s)
let arrs = s.split('')
let arrt = t.split('')
for (let i of arrt) {
let nums = 0, numt = 0
for (let j of arrs) {
if (i == j) ++nums
}
for (let k of arrt) {
if (i == k) ++numt
}
if (nums !== numt) {
return i
}
}
};
解法里面用了三次循环,虽然把题目做出来了但是略显笨重。核心思路是用到计数。重排后的数组里面的每一个元素,在原数组,和新数组中的个数是否相等。
后面看了官解发现另外的思路,大部分人可能想到的是先sort排序然后循环对比,还有java里面用异或的,这个还木有去了解是Java特有的还是js也可以。
写这段代码复习到了的相关知识点:
字符串转换为数组的方法:
- split('分隔符')方法: 分隔符选填,该方法无法处理采用两个代码单元的字符,如表情符号。
- 展开运算符[...]、解构赋值:如代码
- Array.from(): 将类似数组的对象和可遍历的对象转化为真正的数组,不改变原对象。该方法可传三个参数,第一个参数是待转换对象;第二个参数提供一个类似
map的功能,对每个元素进行处理,将处理后的结果返回到即将生成的新数组中;如果map函数里面用到了this关键字,还可以传入Array.from的第三个参数,用来绑定this。
Array.from([1,2,3], (i) => { i+1 })
Array.from({ length: 3 }); // [ undefined, undefined, undefined ]
数组的循环方式:
for for...in for...of forEach
这个很基础了,但是自己对细节上的掌握还是不够,应用的时候不够灵活,比如
for...in遍历数组的索引,更适合遍历对象,可以使用break、continue、return;for...of遍历数组的值,适合遍历数组/字符串/map/set 等迭代器对象的集合,但是不能遍历普通对象,可以使用break、continue、return;forEach使用简简洁,但是不可以使用continue语句跳过一次循环和使用break语句结束循环。
而且自己在写代码的时候居然试图直接在string后面使用forEach,这是会报类型错误.forEach is not a function
但是官解里面的用到字符编码,累加累减思路真的很巧妙。学习一下。
官解1:计数:首先遍历原字符串 s,对其中的每个字符都将计数值加 1;然后遍历字符串 t,对其中的每个字符都将计数值减 1。当发现某个字符计数值为负数时,说明该字符在字符串 t 中出现的次数大于在字符串 s 中出现的次数,因此该字符为被添加的字符。
var findTheDifference = function(s, t) {
// 生成数组
const cnt = new Array(26).fill(0);
// 对字符串使用 for...of,是一个个元素组成的数组
for (const ch of s) {
// charCodeAt() 是一种字符串方法,用于检索字符串中特定位置的字符的Unicode 值
// string.charCodeAt([position]) ,如果不填position则默认为0
// 将每个字符串里面的字符的Unicode - 小a的Unicode值,作为数组下标
// 分别将每个字母放在对应的数组位置,且能保持和字母表的顺序一致
cnt[ch.charCodeAt() - 'a'.charCodeAt()]++;
}
for (const ch of t) {
cnt[ch.charCodeAt() - 'a'.charCodeAt()]--;
if (cnt[ch.charCodeAt() - 'a'.charCodeAt()] < 0) {
return ch;
}
}
return ' ';
};
回顾的知识点:js的charCodeAt,还有关于数组的生成
创建一个数组:
- 字面量方式:
const arr1 = []const arr2 = [1,2,3] - 构造器生成:
const a1 = new Array()// []const a2 = new Array(2)// [ , ]const a3 = new Array(3,6,7,)// [3,6,7]
这里会发现字面量生成时,会因为参数的不同而得到不同的结果,所以有Array.of()返回由所有参数值组成的数组,如:const a4 = Array.of(2) // [2]
官解2:求和:ASCLL码值求和,两个和值相减所得即为增减的字符的ASCLL码值。
var findTheDifference = function(s, t) {
let as = 0, at = 0;
for (let i = 0; i < s.length; i++) {
as += s[i].charCodeAt();
}
for (let i = 0; i < t.length; i++) {
at += t[i].charCodeAt();
}
return String.fromCharCode(at - as);
// fromCharCode()是字符串对象的一个方法,它将Unicode转换为字符(字符串)
// String.fromCharCode(num1, ..., numN)一个或者多个参数
};