如何解决经典数组元素删除问题:删除指定索引时后续索引失效
高效解决方案
针对极长数组按原始索引批量删除的需求,有两种线性时间复杂度的最优方案,核心逻辑都是基于原始索引判断是否保留,完全避免删除操作导致的索引偏移问题:
方案1:哈希集合法(内存充足时首选,实现最简单)
时间复杂度O(n + k),n为数组X长度,k为待删索引数组Y长度(Y为短数组,预处理成本可忽略)
- 第一步:先对Y做去重处理,再转成哈希集合,实现O(1)时间判断某个原始索引是否需要删除
- 第二步:遍历原数组X的所有元素,同步记录当前元素的原始索引,只要原始索引不在待删集合中,就加入结果数组
- 代码示例(Python):
X = [1,5,3,4,1,2,2] Y = [1,3,4] del_set = set(Y) res = [num for idx, num in enumerate(X) if idx not in del_set] # 输出res: [1,3,2,2]
方案2:原地修改法(内存不足时首选,无额外大内存开销)
时间复杂度O(n + k logk),仅需要O(k)的额外空间存储排序后的待删索引,不需要开辟和X等长的新数组
- 第一步:对Y做去重+升序排序
- 第二步:初始化偏移量
offset = 0,遍历X的每个原始索引i:- 用二分查找判断i是否在排序后的Y中(因为Y有序,二分查找时间O(logk),k很小的情况下可忽略)
- 如果是待删索引:
offset += 1,跳过当前元素 - 如果是保留索引:将
X[i]赋值到X[i - offset]的位置
- 第三步:将X截断到长度
len(X) - len(Y)即可得到结果 - 代码示例(Python):
import bisect X = [1,5,3,4,1,2,2] Y = [1,3,4] # 去重+排序 sorted_del = sorted(set(Y)) offset = 0 n = len(X) k = len(sorted_del) for i in range(n): pos = bisect.bisect_left(sorted_del, i) if pos < k and sorted_del[pos] == i: offset +=1 else: X[i - offset] = X[i] # 截断数组 X = X[:n - offset] # 输出X: [1,3,2,2]
注意事项
- 提前过滤Y中超出X合法索引范围的无效值,避免判断逻辑出错
- 如果Y本身已经是升序且无重复,可以跳过排序去重步骤,进一步提升效率
内容的提问来源于stack exchange,提问作者trshmanx
相关产品推荐
相关产品推荐

