Go语言数组去重两种常用方法:Map法与双指针法
在Go语言开发中,数据清洗常涉及去除切片中的重复元素。根据数据是否已排序及内存限制不同,主要采用两种策略:利用 map 记录键值的唯一性进行通用去重,以及通过双指针技术实现排序数组的原地去重。
利用 Map 唯一性进行通用数组去重
map 的核心特性是其 key 必须唯一。我们可以遍历原始数组,将数组元素作为 key 存入 map。由于重复元素作为 key 时会覆盖之前的值(或保持原样),从而自动过滤掉重复项。最后再次遍历 map 提取 value 即可得到去重后的切片。
注意:map 是无序的,因此转换回 slice 后元素的相对顺序可能与原数组不一致。
第1步:定义数据结构与示例数据
准备一个包含重复字符串的切片和一个用于存储键值对的 map。
var strMap = make(map[string]string)
strSlice := []string{"slice", "int", "string", "int", "boolean", "string"}
第2步:遍历切片构建 Map
使用 range 遍历切片,将每个元素同时赋值给 map 的 key 和 value。若遇到重复元素,map 会保留最后一次写入的记录(对于同值key-value对无影响)。
for _, v := range strSlice {
strMap[v] = v
}
第3步:从 Map 还原为 Slice
创建一个新的切片,遍历 map 并将 value 追加到新切片中。此时得到的即为去重后的结果。
var secondStr []string
for _, value := range strMap {
secondStr = append(secondStr, value)
}
// 结果示例:["slice", "int", "string", "boolean"]
排序数组的原地去重(双指针法)
针对已排序的整数数组,题目通常要求原地修改输入数组且只使用 O(1) 额外空间。此类问题可采用“快慢指针”或称为“左右游标”的策略解决。
第1步:理解题意与边界条件
- 目标:删除重复项,使每个元素只出现一次,返回新长度。
- 约束:不能使用额外数组空间,需在原数组上操作。
- 输出:数组前 N 个位置应为去重后的元素,N 为新长度。超出部分的元素无需理会。
- 边界:若输入数组为空,直接返回 0。
第2步:初始化双指针
设置两个整型变量 left 和 right:
left:指向当前已去重部分的最后一个有效元素索引(初始为 0)。right:负责扫描后续元素的游标(初始为 1)。
第3步:遍历与比较
当 right 小于数组长度时循环执行以下逻辑:
- 判断相等:若
nums[left] == nums[right],说明遇到重复值,left不动,right继续向后移动以寻找下一个不同的值。 - 更新位置:若
nums[left] != nums[right],说明找到新的唯一元素。先将left向前移动一位(left++),然后将nums[right]的值复制到nums[left]。
第4步:返回新长度
循环结束后,left 指向的是去重后最后一个元素的位置。因此,新长度为 left + 1。
func removeDuplicates(nums []int) int {
if len(nums) == 0 {
return 0
}
left, right := 0, 1
for right < len(nums) {
if nums[left] != nums[right] {
left++
nums[left] = nums[right]
}
right++
}
// 仅用于演示查看结果,实际函数只需 return left + 1
fmt.Println(nums[:left+1])
return left + 1
}复杂度分析:该算法时间复杂度为 O(N),其中 N 为数组长度,因为指针仅遍历数组一次;空间复杂度为 O(1),仅使用了几个整型变量。
总结
处理 Go 语言数组去重时,若无需保持原有顺序且允许额外空间,使用 map 是最简洁的方案;若面对排序数组且受限于 O(1) 空间复杂度,双指针法是标准解法。开发者应根据具体业务场景和性能要求选择合适的方法。以上就是 Go 语言数组去重两种常用方法的详细内容,更多关于 Go 语言切片处理的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













