1347.制造字母异位词的最小步骤数

题干在此

我的解题

先将字符串转化为数组,然后将两数组相同的元素删除,处理后的数组长度便为最小步骤数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var minSteps = function(s, t) {
const arrT = []
const arrS = []
for(let i =0; i<t.length; i++) {
arrT.push(t.slice(i,i+1))
arrS.push(s.slice(i,i+1))
}
arrT.map((v)=>{
const index = arrS.findIndex(k => k===v)
if(index !== -1) {
arrS.splice(index, 1)
}
})
return arrS.length
}

不出所料的还是超时了,到在长度为50000的字符串的测试用例下。

map * findIndex 的时间复杂度还是太高了。

后来想到字符串的API也支持如此操作,优化了代码。

1
2
3
4
5
6
7
var minSteps = function(s, t) {
let res = s
for (let i = 0; i<t.length; i++) {
res = res.replace(t.charAt(i), "")
}
return res.length
}

时间复杂度还是很高,但是提交通过了。

用js写了两道算法后,我发现js不适合做算法。很多API无法直接感受到它的时间复杂度,需要去搜索才能大概了解它的复杂度。

本身写代码时候都是直接用API,做题时候却不太能用这些,两者很矛盾。

感觉如果想坚持做算法,还是要用一门编译型语言来做题,解释型的语言还是比较吃亏。

解题思路

我一开始没想到map,map的性能还是很高的。

用哈希表示s的所有字母出现的次数,遍历t,该字母在s出现一次,哈希表该字母减一。哈希表所有正值求和,即为最小步骤数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var minSteps = function(s, t) {
let map = new Map(), ans = 0;
for (let i = 0, len = s.length; i < len; i++) {
let c = s.charAt(i)
if (!map.has( c )) {
map.set( c, 1 )
} else {
map.set( c, map.get( c ) + 1 )
}
}
for (let i = 0, len = t.length; i < len; i++) {
let c = t.charAt(i)
if (map.has( c )) {
map.set( c, map.get( c ) - 1 )
}
}
map = [...map]
for (let i = 0, len = map.length; i < len; i++) {
if (map[i][1] > 0) {
ans += map[i][1]
}
}
return ans
}

总结

注意时间复杂度,不要递归,不要循环套循环,这样会使得O(n)超级加倍。

js不适合做算法,它所提供的方法基本不能直观观察出时间复杂度,性能还差,尽早学C。

Author: Kari WanG
Link: https://mingz.wang/2020/06/01/1347-制造字母异位词的最小步骤数/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.