删除字符串中出现次数最少的字符,怎样保持原顺序?
先理解原理和示例,再练习完整口述与追问。
回答要点
两遍计数与筛选;删除所有并列最少字符;码点与字形;O(n);空输入。
原理拆解
第一遍统计每个字符频率,扫描频率表找到最小值,第二遍按原字符串顺序保留频率不等于最小值的字符。不能把字符排序后再删除,否则改变顺序;最小频率可能对应多个字符,都要按题意处理。这里用 for…of/Array.from 按 Unicode 码点遍历,不等于完整用户可见字形。
示例与推演
function removeLeastFrequent(text) {
if (typeof text !== 'string') throw new TypeError('输入必须是字符串')
const counts = new Map()
for (const char of text) counts.set(char, (counts.get(char) || 0) + 1)
if (counts.size === 0) return ''
let minimum = Infinity
for (const count of counts.values()) minimum = Math.min(minimum, count)
return Array.from(text).filter(char => counts.get(char) !== minimum).join('')
}
aabcc 中 a/c 各 2 次,b 为 1 次,输出 aacc;abc 三者并列最少,输出空字符串。时间 O(n),除输出外计数表 O(k),当前 Array.from/filter 还使用 O(n) 临时空间。
易错点
组合 emoji、重音组合字符若按“用户看到的一个字符”计算,需要分字形机制。字符全部频率相同是否全删,应先确认题意。
参考回答可直接练习口述
我先计数找出最低频率,再按原顺序过滤,删除所有并列最低项。解释字符单位、空输入和并列情况,并准确计算临时数组与输出空间。