Leetcode 567. Permutation in String

https://leetcode.com/problems/permutation-in-string/description/
https://discuss.leetcode.com/topic/87845/java-solution-sliding-window
感谢@shawngao的sliding-window的提示

Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. In other words, one of the first string’s permutations is the substring of the second string.

Example 1:

Input:s1 = "ab" s2 = "eidbaooo"
Output:True
Explanation: s2 contains one permutation of s1 ("ba").

Example 2:

Input:s1= "ab" s2 = "eidboaoo"
Output: False

Note:
The input strings only contain lower case letters.
The length of both given strings is in range [1, 10,000].

暴力解法肯定会爆炸。
有了想统计单个char的想法,然后看见discuss中sliding-window的时候,思路一下子就豁然开朗了,通过在s2上维护一个s1长的sliding-window,然后统计这段长度中的char的数量,若与s1的数量一致,则意味着s2的这段子串是s1的一个排列。
结合javascript的语言结构,hash统计的实现很是简单

var checkInclusion = function(s1, s2) {
    if (s2.length < s1.length || s2.length == 0) {
        return false;
    }
    const hashMap = {};
    const len = s1.length;
    for (let i = 0; i < len; ++i) {
        if (!hashMap[s1[i]]) {
            hashMap[s1[i]] = 0;
        }
        if (!hashMap[s2[i]]) {
            hashMap[s2[i]] = 0;
        }
        hashMap[s1[i]]++;
        hashMap[s2[i]]--;
    }
    if (isAllZero(hashMap)) {
        return true;
    }

    for (let i = len; i < s2.length; ++i) {
        if (!hashMap[s2[i]]) {
            hashMap[s2[i]] = 0;
        }
        hashMap[s2[i]]--;
        hashMap[s2[i-len]]++;
        if (isAllZero(hashMap)) {
            return true;
        }
    }
    return false;
};

const isAllZero = (hashMap) => {
    const keys = Object.keys(hashMap);
    for (let i = 0; i < keys.length; ++i) {
        if (hashMap[keys[i]]) {
            return false;
        }
    }
    return true;
}

然而beat 7%,那是当然,毕竟是object,提速的话改成array试试

var checkInclusion = function(s1, s2) {
    if (s2.length < s1.length || s2.length === 0) {
        return false;
    }
    const charArr = Array(26).fill(0);
    const len = s1.length;
    const offset = 'a'.charCodeAt(0);
    for (let i = 0; i < len; ++i) {
        charArr[s1.charCodeAt(i) - offset]++;
        charArr[s2.charCodeAt(i) - offset]--;
    }
    if (isAllZero(charArr)) {
        return true;
    }
    for (let i = len; i < s2.length; ++i) {
        charArr[s2.charCodeAt(i) - offset]--;
        charArr[s2.charCodeAt(i-len) -offset]++;
        if (isAllZero(charArr)) {
            return true;
        }
    }
    return false;
};

const isAllZero = (charArr) => {
    for (let i = 0; i < charArr.length; ++i) {
        if (charArr[i]) {
            return false;
        }
    }
    return true;
}

提速超明显,beat 100%,估计是Array(26).fill(0)和len,offset常量提前算的原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值