查找字符串b中较小字符串s的所有排列(JavaScript)

马克·弗莱彻

我一直在尝试找到以下问题的O(n)解决方案:在字符串b中查找字符串s的字谜(排列)数,其中s.length始终小于b.length

我读到最佳解决方案包括跟踪较小字符串中的字符频率,并在滑动窗口跨较大字符串移动时对它进行相同的操作,但是我不确定该实现实际上如何工作。现在,我的解决方案不起作用(请参阅评论),但即使可行,也将花费O(s + sn)的时间。

编辑:示例输入:('aba', 'abaab')输出:3,因为'aba'存在于b中,从索引0,索引'baa'1和索引'aab'2开始。

function anagramsInStr(s,b) {

    //O(s)
    let freq = s.split("").reduce((map, el) => {
        map[el] = (map[el] + 1) || 1;
        return map;
    }, {});

    let i = 0, j = s.length;
    // O(n)
    for (let char in b.split("")) {
        // O(s)
        if (b.length - char + 1 > s.length) {

            let window = b.slice(i,j);

            let windowFreq = window.split("").reduce((map, el) => {
                map[el] = (map[el] + 1) || 1;
                return map;
            }, {});
            // Somewhere about here compare the frequencies of chars found in the window to the frequencies hash defined in the outer scope. 
            i++;
            j++;

        }
    }
}
用户名

仔细阅读评论,如果您有任何疑问,请告诉我:

function countAnagramOccurrences(s, b) {
  var matchCount = 0;

  var sCounts = {}; // counts for the letters in s
  var bCounts = {}; // counts for the letters in b

  // construct sCounts
  for (var i = 0; i < s.length; i++) {
    sCounts[s[i]] = (sCounts[s[i]] || 0) + 1;
  }

  // all letters that occur in sCounts
  var letters = Object.keys(sCounts);

  // for each letter in b
  for (var i = 0; i < b.length; i++) {
    // maintain a sliding window
    // if we already have s.length items in the counts, remove the oldest one
    if (i >= s.length) {
      bCounts[b[i-s.length]] -= 1;
    }
    // increment the count for the letter we're currently looking at
    bCounts[b[i]] = (bCounts[b[i]] || 0) + 1;

    // test for a match (b counts == s counts)
    var match = true;
    for (var j = 0; j < letters.length; j++) {
      if (sCounts[letters[j]] !== bCounts[letters[j]]) {
        match = false;
        break;
      }
    }
    if (match) {
      matchCount += 1;
    }
  }

  return matchCount;
}

console.log(countAnagramOccurrences('aba', 'abaab')); // 3

编辑

关于运行时的注释:这是O(nk + m)的一种,其中ns的长度mb的长度kb中唯一字符的数量由于m总是小于n,我们可以减小为O(nk),并且由于k由固定常数(字母的大小)限制,所以我们可以进一步减小为O(n)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章