• 作者:老汪软件技巧
  • 发表时间:2024-09-01 11:02
  • 浏览量:

给你两个下标从0开始的字符串s和target。你可以从s取出一些字符并将其重排,得到若干新的字符串。

从s中取出字符并重新排列,返回可以形成target的最大副本数。

示例 1:

输入: s = "ilovecodingonleetcode", target = "code"
输出: 2
解释:
对于 "code" 的第 1 个副本,选取下标为 4567 的字符。
对于 "code" 的第 2 个副本,选取下标为 17181920 的字符。
形成的字符串分别是 "ecod""code" ,都可以重排为 "code" 。
可以形成最多 2"code" 的副本,所以返回 2

示例 2:

输入: s = "abcba", target = "abc"
输出: 1
解释:
选取下标为 012 的字符,可以形成 "abc"1 个副本。 
可以形成最多 1"abc" 的副本,所以返回 1 。
注意,尽管下标 34 分别有额外的 'a''b' ,但不能重用下标 2 处的 'c' ,所以无法形成 "abc" 的第 2 个副本。

示例 3:

输入: s = "abbaccaddaeea", target = "aaaaa"
输出: 1
解释:
选取下标为 036912 的字符,可以形成 "aaaaa"1 个副本。
可以形成最多 1"aaaaa" 的副本,所以返回 1

提示:

一般解法

function rearrangeCharacters(s: string, target: string): number {
  const OFFSET = "a".charCodeAt(0);
  const cnt = new Array(26).fill(0);
  for (const char of s) {
    cnt[char.charCodeAt(0) - OFFSET]++;
  }
  let ans = 0;
  while (true) {
    for (const char of target) {
      if (--cnt[char.charCodeAt(0) - OFFSET] === -1) return ans;
    }
    ans++;
  }
}

性能更好的解法

function rearrangeCharacters(s: string, target: string): number {
  const OFFSET = "a".charCodeAt(0);
  const cnt = new Array(52).fill(0);
  for (const char of s) {
    cnt[char.charCodeAt(0) - OFFSET]++;
  }
  for (const char of target) {
    cnt[char.charCodeAt(0) - OFFSET + 26]++;
  }
  let min = Number.MAX_VALUE;
  for (let i = 0; i < 26; i++) {
    const targetCnt = cnt[i + 26];
    const sCnt = cnt[i];
    if (targetCnt !== 0) {
      min = Math.min(min, Math.floor(sCnt / targetCnt));
    }
  }
  return min;
}