CodeSignal commonCharacterCount题双循环实现跳元素问题排查
问题排查与修复方案
根因定位
你的代码存在3处核心逻辑错误,直接导致字符跳过、匹配结果错误的问题:
splice方法入参错误:Array.splice()第一个参数要求是待删除元素的索引位置,你代码中传入的是当前字符值arrayOne[i],会被隐式转换为0,导致每次匹配成功都会删除数组第一个元素,而非当前匹配的i位置元素。- 删除数组元素后未调整外层循环索引:删除
arrayOne的元素后,原i+1位的元素会前移到i位,此时外层循环执行i++会直接跳过这个新移动到i位的元素,就是你遇到的跳过"b"的直接原因。 - 匹配成功后未终止内层循环、未清理s2的匹配元素:单个字符匹配成功后没有跳出内层循环,也没有删除s2中已匹配的元素,会导致同一个s2字符被重复匹配多次。
修复方案(兼容原双循环逻辑)
直接在你的原有代码基础上调整错误逻辑即可:
function commonCharacterCount(s1, s2) { const arrayOne = s1.split("") const arrayTwo = s2.split("") let matches = 0; for (let i = 0; i < arrayOne.length; i++) { for (let j = 0; j < arrayTwo.length; j++) { if (arrayOne[i] === arrayTwo[j]) { matches++ arrayOne.splice(i, 1) // 传入索引i删除当前匹配元素 arrayTwo.splice(j, 1) // 删除s2中已匹配元素,避免重复匹配 i-- // 索引回退1,避免跳过后续元素 break // 匹配成功直接跳出内层循环,处理s1下一个元素 } } } return matches }
更优实现(计数法,时间复杂度O(n+m))
不需要修改数组,遍历两次字符串即可得到结果,性能优于双循环方案:
function commonCharacterCount(s1, s2) { const charMap = {} // 统计s1所有字符的出现次数 for (const char of s1) { charMap[char] = (charMap[char] || 0) + 1 } let count = 0 // 遍历s2匹配计数 for (const char of s2) { if (charMap[char] > 0) { count++ charMap[char]-- } } return count }
内容的提问来源于stack exchange,提问作者Sean Jones
相关产品推荐
相关产品推荐

