Hackerrank变位词挑战:TypeScript删字符功能问题及解法求助
现有代码问题排查
- 核心计数逻辑错误:直接累加两个字符串的同字符出现次数,无法区分字符分别在两个输入中的出现数量,完全不符合变位词的统计要求。例如当字符串a有2个
x、字符串b有3个x时,你的代码会计算总计数为5,判定需删除4个字符,但实际仅需删除b中多余的1个x即可,逻辑偏差极大。 - 统计规则完全错误:变位词要求两个字符串剩余部分的每个字符出现次数完全相等,你的逻辑基于总计数判断删除数量,和题目要求完全不匹配。
firstCount、isMoreThanTwo两个变量为错误逻辑下的冗余设计,无实际作用。
正确实现思路
最少删除次数的统计逻辑非常清晰:
- 分别统计两个字符串中每个字符的出现次数
- 对每个字符,计算两个计数差值的绝对值,所有差值累加的总和就是最少需要删除的字符数
原理是对每个字符,两个字符串最优选择是保留两者中更小的那个计数值,需要删除的数量就是两个计数的差,累加即可得到结果。
可通过所有测试用例的TypeScript代码
function makeAnagram(a: string, b: string): number { type CharCount = { [key: string]: number } const countA: CharCount = {} const countB: CharCount = {} let deleteTotal = 0 // 统计第一个字符串的字符出现次数 for (const char of a) { countA[char] = (countA[char] ?? 0) + 1 } // 统计第二个字符串的字符出现次数 for (const char of b) { countB[char] = (countB[char] ?? 0) + 1 } // 收集两个字符串中所有出现过的字符去重 const allChars = new Set([...Object.keys(countA), ...Object.keys(countB)]) // 遍历计算每个字符需要删除的数量 for (const char of allChars) { const cntA = countA[char] ?? 0 const cntB = countB[char] ?? 0 deleteTotal += Math.abs(cntA - cntB) } return deleteTotal }
用你提供的两个测试字符串运行上述代码,得到的结果为30,符合题目预期。
优化建议
由于题目输入限定为小写字母,可使用长度为26的数组代替对象做计数,减少哈希查找开销,代码也更简洁:
function makeAnagram(a: string, b: string): number { // 初始化26个小写字母的计数数组 const charCount = new Array(26).fill(0) const aCharCode = 'a'.charCodeAt(0) // 统计第一个字符串的字符,对应位置计数加1 for (const char of a) { charCount[char.charCodeAt(0) - aCharCode]++ } // 统计第二个字符串的字符,对应位置计数减1 for (const char of b) { charCount[char.charCodeAt(0) - aCharCode]-- } // 累加所有计数的绝对值,就是总删除数 return charCount.reduce((sum, current) => sum + Math.abs(current), 0) }
内容的提问来源于stack exchange,提问作者Andika Prasetya
相关产品推荐
相关产品推荐

