day3 字符串的排列
(中等题)给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。
输入: s1 = "ab" s2 = "eidbaooo"
输出: True
解释: s2 包含 s1 的排列之一 ("ba").
中等题就是不一样.....
没写出来, 分析一下别人写的吧, 运行时间第一名
var checkInclusion = function (s1, s2) { var standard = {}; let slow = 0; let map = {}; for (let i = 0, len = s1.length; i < len; i++) { !standard[s1[i]] ? standard[s1[i]] = 1 : standard[s1[i]]++; } // 先把s1字符串里面的字母和数量都统计出来, 保存在stabdard对象里面
for (let i = 0, len = s2.length; i < len; i++) { let current = s2[i]; document.write(current + ' ') // 如果这个元素在s1里面没有, 说明统计的map废了, 重新统计 同时移动slow指针 if (!standard[current]) { slow = i + 1; map = {}; continue; } // i移动的时候,字典中字符数量增加, 把是standard里面的统计到map里面 !map[current] ? map[current] = 1 : map[current]++; // 如果统计的字母数量超过了s1里面的, 则移动slow指针 while (map[current] > standard[current]) { map[s2[slow++]]--; } if (i - slow + 1 === s1.length) { return true; } } return false; };
冷静分析:
这个解题思路就是, 先把字符串s1里面的字母和数量保存到standard对象里面, 然后取出s2里面的每一个字母, 看看standard里面有没有, 有的话继续, 没有的话跳过, 指针向后移,
如果standard里面有, 再看看map里面有没有, 没有保存为1, 有的话数量加1, 最后看看统计的数量是不是超过了, 超过了就舍弃前面的保留后面的, 同时指针后移一位, 继续统计
让指针加1的条件是:
1. s2里面有, s1里面没有的字符串
2. s2有, s1也有但是s2比s1多的数量
循环过后i - slow + 1 和s1的长度比对, 一样的话就返回true, 否则就返回false, 因为 i 是从0开始的, 所以 + 1
举例:
var s1 = 'abbc', s2 = 'ddfgdfgdcbbadfsdsf'; checkInclusion(s1, s2);
按照以上算法, 会使slow加1的有 : d, d, f, g, d, f, g, d 最后slow是8
而 i 是 11 (循环到a时) 所以算法成立, 返回true
今天就分析到这里了..