Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
字符串的排列
给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
换句话说,s1 的排列之一是 s2 的 子串 。
示例 1:
输入:s1 = "ab" s2 = "eidbaooo"
输出:true
解释:s2 包含 s1 的排列之一 ("ba").
示例 2:
输入:s1= "ab" s2 = "eidboaoo"
输出:false
思路分析
方法一
- 先将
s2分成s1长度连续的子串; - 定义
help方法来判断,s2的字串中是否 含有s1的排列; - 如果
s2的字串中有一个含有s1的排列,那么返回true,否则返回false; - 最后的结果是 超出时间限制,里面有太多的循环,太多的查找了。
方法二
- 其他步骤还是按照方法一的来处理,优化了
help方法; - 创建长度
26的数组count1和count2,统计s1字符 以及s2的子串出现的次数; - 判断
count1.join('') === count2.join('')。
AC 代码
方法一
/**
* @param {string} s1
* @param {string} s2
* @return {boolean}
*/
var checkInclusion = function(s1, s2) {
const len = s1.length
const res = []
for(let i = 0; i <= s2.length - len; i++) {
res.push(help(s1, s2.substr(i, len)))
}
console.log(res)
return res.some(item=>item)
};
var help = function(s1, s2) {
for(let i = 0; i < s1.length; i++) {
const index = s2.indexOf(s1[i])
if(index === -1) {
return false
} else {
s2 = s2.replace(s1[i], 'X')
}
}
return true
}
结果: 超出时间限制
方法二
/**
* @param {string} s1
* @param {string} s2
* @return {boolean}
*/
var checkInclusion = function(s1, s2) {
const len = s1.length
const res = []
for(let i = 0; i <= s2.length - len; i++) {
res.push(help(s1, s2.substr(i, len)))
}
console.log(res)
return res.some(item=>item)
};
var help = function(s1, s2) {
const count1 = new Array(26).fill(0);
const count2 = new Array(26).fill(0);
for(let i = 0; i < s1.length; i++) {
count1[s1[i].charCodeAt(0) - 97]++;
count2[s2[i].charCodeAt(0) - 97]++;
}
return count1.join('') === count2.join('')
}
结果:
- 执行结果: 通过
- 执行用时:616 ms, 在所有 JavaScript 提交中击败了16.14%的用户
- 内存消耗:49.3 MB, 在所有 JavaScript 提交中击败了5.91%的用户
- 通过测试用例:107 / 107