You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift实现sockMerchant数组重复元素配对计数功能运行异常排查

代码问题分析
  • 提前终止逻辑错误:return numberOfPairs被放在for循环内部,只要当前遍历到的元素没有可配对的重复项(首次和末次索引相同),就会直接终止函数返回结果,不会遍历后续元素。比如第二个测试用例遍历到元素2时,检测到没有重复直接返回,自然无法得到正确结果。
  • 元素删除顺序错误:你先删除索引更小的indexOfFirstElement,再删除索引更大的indexOfLastElement。删除第一个元素后,数组整体长度减1,所有索引大于indexOfFirstElement的元素都会前移一位,原本的indexOfLastElement已经失效,此时再删除会导致索引越界或者删错元素。正确的删除顺序应该是先删索引更大的,再删索引更小的,避免小索引的删除操作影响大索引的有效性。
  • 遍历范围固定问题:初始化for循环时用的0..<array.count是取循环执行前的数组长度计算的固定值,后续你不断删除元素导致数组长度变小,循环还是会遍历到超出当前数组长度的索引,触发越界崩溃。
修复后的原逻辑代码
func sockMerchant(n: Int, ar: [Int]) -> Int {
    var array = ar
    var numberOfPairs = 0
    var i = 0
    // 用while循环动态判断数组长度,替代固定范围的for循环
    while i < array.count {
        let element = array[i]
        guard let indexOfFirstElement = array.firstIndex(of: element),
              let indexOfLastElement = array.lastIndex(of: element),
              indexOfFirstElement != indexOfLastElement else {
            // 当前元素无配对,遍历下一个
            i += 1
            continue
        }
        numberOfPairs += 1
        // 先删大索引,再删小索引,避免索引失效
        array.remove(at: indexOfLastElement)
        array.remove(at: indexOfFirstElement)
    }
    return numberOfPairs
}
更优实现方案(时间复杂度O(n))

不用修改数组,直接用哈希表统计每个元素的出现频率,每个元素的配对数等于出现次数除以2取整,累加所有元素的配对数即可,逻辑更简单性能更高:

func sockMerchant(n: Int, ar: [Int]) -> Int {
    var countDict = [Int: Int]()
    ar.forEach { countDict[$0, default: 0] += 1 }
    return countDict.values.reduce(0) { $0 + $1 / 2 }
}

内容的提问来源于stack exchange,提问作者Artun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 11:54:01