【问题标题】:Repeat String Infinitely - Return Count of Specific Character Within N Length of Infinite String - JavaScript无限重复字符串 - 返回无限字符串 N 长度内特定字符的计数 - JavaScript
【发布时间】:2019-07-11 14:57:37
【问题描述】:

试图解决这个HackerRank challenge

Lilah 有一个字符串,s,由她无限次重复的小写英文字母组成。

给定一个整数 n,找出并打印 Lilah 无限字符串的第一个字母中的字母 a 的数量。

例如,如果字符串s = abcacn = 10,我们考虑的子字符串是abcacabcac,第一个她的无限字符串的 10 个字符。子字符串中有 4 个“a”。

我写道:

function repeatedString(s, n) {

    s = s.repeat(n);
    s = s.slice(0, n);
    
    let array = Array.from(s);
    let count = 0;
    for (let i = 0; i < array.length; i++) {
        let char = array[i];
        if (char.match(/[a]/gi)) {
            count++;
        }
    }
    return count;
}
console.log(repeatedString("abcac", 10)); 

但HackerRank 显然不喜欢s = s.repeat(n);

我不确定如何生成适当长度的字符串以从中进行切片。 s = s.repeat(Infinity) 不起作用,并且 s 在作为参数传入时已经重复了无数次。

即console.logging(s),最初,日志

abcac

在这种情况下。

我也试过了:

function repeatedString(s, n) {

  let j = n;
  let newString = "";
  while (n > 0) {
      newString += s;
      n--;
  }
  
  newString = newString.slice(0, j);
  let count = 0;
  let array = Array.from(newString);
 
  for (let i = 0; i < array.length; i++) {
      let char = array[i];
      if (char.match(/[a]/gi)) {
          count++;
      }
  }
  return count;
}
console.log(repeatedString("abcac", 10)); 

但这导致了超时错误。

关于如何创建一个有效长度的字符串进行切片还有其他想法吗?

编辑

约束:

1

1

对于 25% 的测试用例,n

【问题讨论】:

  • 如果 s 包含 "a" 3 次,并且 s 被重复四次以达到长度 n,那么答案是 3 * 4。对于 n= 无穷大,这将是 3 * 无穷大,这将导致无穷大...当然,您必须考虑 s.length % n !== 0,但这并不太复杂。
  • 对于第二个 sn-p,我没有收到超时错误。其他人也是这样吗?
  • @Tuneer 导致 HackerRank 出现超时错误,下面的所有答案也是如此。
  • @JonasWilms 在编辑中为 n 添加了约束 - 1 &lt;= n &lt;= 10^12

标签: javascript arrays string


【解决方案1】:

实际上重复字符串 n 次是对内存和运行时间的巨大浪费。

只需计算整个字符串的重复频率乘以字符串有多少个as 加上s.slice(0, n%s.length) 部分中as 的数量

您的运行时间会下降到 s.length 而不是 n

function repeatedString(s, n) {
  var r = n % s.length,
    m = (n - r) / s.length,
    count = 0;

  for (var i = 0; i < s.length; ++i) {
    if (s[i] === "a") {
      count += m + (i < r);
    }
  }
  return count;
}

console.log(repeatedString("abcac", 1234567890));

【讨论】:

    【解决方案2】:

    我对此进行了测试并且知道它有效。本质上,我不是在创建一个新字符串,我只是找出我必须将原始字符串乘以多少次才能截断它。然后我将该数字乘以原始字符串中有多少个 a。

    function repeatedString(s, n) {
    
        var charLength = s.length;
        var repeat = Math.floor(n/charLength);
        var remainder = n%(charLength);
        var strCut = s.slice(0, remainder);
        
        let count = 0;
        let arrayX = Array.from(s);
        for (let i = 0; i < arrayX.length; i++) {
            let char = arrayX[i];
            if (char.match(/[a]/gi)) {
                count++;
            }
        }
        
        count = count * repeat;
        
        let arrayY = Array.from(strCut);
        for (let i = 0; i < arrayY.length; i++) {
            let char = arrayY[i];
            if (char.match(/[a]/gi)) {
                count++;
            }
        }
    
        return count;
    }
    
    console.log(repeatedString("abcac", 10)); 

    【讨论】:

    • 需要也适用于其他字符串,即"aba",尽管我认为我们在正确的轨道上 - 这里没有超时错误。
    • @HappyHands31 将其更改为适用于其他字符串。
    • 是的,我也尝试了这些更改,不幸的是,超时错误:i.imgur.com/1XZeXUg.png
    • @HappyHands31 试试这个。如果还有其他问题,请告诉我。
    【解决方案3】:

    我尝试了一个使用 .repeat 的小型解决方案,但正如 Thomas 所说,它很昂贵,而且运行测试需要很长时间。

    function repeatedString(s, n) {
        const allAs = s.match(/a/g);
        if (!allAs) {
            return 0;
        }
        if (s === 'a') {
            return n;
        }
        const reps = s.repeat(Math.ceil(n/s.length)).slice(0, n).match(/a/g)
        if (!reps) return 0;
        return reps.length;
    };
    
    console.log(repeatedString('abc', 10));
    console.log(repeatedString('abcde', 10));

    但我遵循了 Thomas 的想法,想出了一个更简单的解决方案

    function repeatedString(s, n) {
        const allAs = s.match(/a/g);
        if (!allAs) {
            return 0;
        }
        if (s === 'a') {
            return n;
        }
        const rem = n % s.length;
        const reps = (n-rem)/s.length;
        let count = reps * allAs.length;
        if (rem) {
            const rest = s.slice(0, rem).match(/a/g);
            if (rest) count = count + rest.length
        }
        return count;
    }
    
    console.log(repeatedString('a', 100000));
    console.log(repeatedString('abcde', 10000000000));

    【讨论】:

      【解决方案4】:

      您可以使用while 循环重复原始字符串直到长度匹配,然后使用match 来计算a 的数量。

      function repeatedString(s, n) {
        let i = 0, l = s.length;
        while (s.length < n) s += s[i++ % l]
        return s.match(/a/g).length;
      }
      console.log(repeatedString("abcac", 10));

      【讨论】:

      • 问题是关于n = Infinity
      • 试过了,它的许多测试都失败了,并且需要很长时间才能运行它们。也超级难读
      【解决方案5】:

      我做了这段代码,效果很好。

      function repeatedString(s, n) {
          let modulus = n % s.length;
          let repetition = (n - modulus) / s.length;
          let remainCounts = s.slice(0, modulus).split("").filter((item) => item == "a").length
          
          return (s.split("").filter((item) => item == "a").length * repetition) + remainCounts
      }
      

      enter image description here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 2017-08-19
        • 1970-01-01
        • 1970-01-01
        • 2016-08-26
        • 1970-01-01
        • 2011-04-19
        相关资源
        最近更新 更多