Swift:快速递增大整数数组中大于指定值元素的高效方法
优化递增大数组的元素递增操作
当前的map实现会遍历数组的每一个元素——哪怕前半部分所有元素都小于等于x,也要逐个判断处理,对于500T级别的超大数组来说,这种全量遍历的性能损耗是致命的。
但你的数组是递增有序的,这是核心优化点:所有大于x的元素必然是数组的一段连续后缀,完全不需要逐个检查每个元素。
优化方案
1. 原地修改(最优,避免内存拷贝)
如果允许直接修改原数组,实现一个mutating方法:
- 用二分查找快速定位到第一个大于x的元素的索引
- 从该索引开始,仅遍历后续元素执行加1操作(如果数组是磁盘存储结构,还可直接定位到对应块批量处理,无需全量读取)
代码实现:
extension Array where Element == Int { mutating func incrementElementsLargerThan(_ x: Int) { // 二分查找第一个大于x的位置 var left = 0 var right = self.count while left < right { let mid = left + (right - left) / 2 if self[mid] > x { right = mid } else { left = mid + 1 } } // 从left开始的所有元素都大于x,逐个加1 for i in left..<self.count { self[i] += 1 } } }
2. 返回新数组(非原地场景)
如果必须返回新数组,可以避免拷贝前半部分不需要修改的元素,直接拼接处理后的后缀:
extension Array where Element == Int { func incrementElements(largerThan x: Int) -> [Int] { var left = 0 var right = self.count while left < right { let mid = left + (right - left) / 2 if self[mid] > x { right = mid } else { left = mid + 1 } } // 前半部分直接截取,后半部分处理后拼接 var result = Array(self[0..<left]) result.append(contentsOf: self[left...].map { $0 + 1 }) return result } }
性能提升说明
- 二分查找的时间复杂度是
O(log n),远快于全量遍历的O(n) - 仅处理数组的后缀部分,当x较大时,需要处理的元素数量极少,性能提升极其明显
- 对于磁盘存储的超大数组,可结合分块存储结构,直接定位到需要修改的块,避免全量读取,进一步放大性能优势
内容的提问来源于stack exchange,提问作者Panone
相关产品推荐
相关产品推荐

