Go Program to Remove Duplicates from Slice
seen := make(map[int]bool); for _, v := range slice { if !seen[v] { seen[v] = true; result = append(result, v) } }.Examples
How to Think About It
Algorithm
Code
package main import "fmt" func removeDuplicates(slice []int) []int { seen := make(map[int]bool) var result []int for _, v := range slice { if !seen[v] { seen[v] = true result = append(result, v) } } return result } func main() { nums := []int{1, 2, 2, 3, 4, 4, 5} unique := removeDuplicates(nums) fmt.Println(unique) }
Dry Run
Let's trace the slice [1, 2, 2, 3, 4, 4, 5] through the code
Initialize map and result slice
seen = {}, result = []
Process element 1
1 not in seen, add 1: seen = {1:true}, result = [1]
Process element 2
2 not in seen, add 2: seen = {1:true, 2:true}, result = [1, 2]
Process element 2 again
2 in seen, skip
Process element 3
3 not in seen, add 3: seen = {1:true, 2:true, 3:true}, result = [1, 2, 3]
Process element 4
4 not in seen, add 4: seen = {1:true, 2:true, 3:true, 4:true}, result = [1, 2, 3, 4]
Process element 4 again
4 in seen, skip
Process element 5
5 not in seen, add 5: seen = {1:true, 2:true, 3:true, 4:true, 5:true}, result = [1, 2, 3, 4, 5]
| Iteration | Element | Seen Map Keys | Result Slice |
|---|---|---|---|
| 1 | 1 | [1] | [1] |
| 2 | 2 | [1 2] | [1 2] |
| 3 | 2 | [1 2] | [1 2] |
| 4 | 3 | [1 2 3] | [1 2 3] |
| 5 | 4 | [1 2 3 4] | [1 2 3 4] |
| 6 | 4 | [1 2 3 4] | [1 2 3 4] |
| 7 | 5 | [1 2 3 4 5] | [1 2 3 4 5] |
Why This Works
Step 1: Use a map to track seen elements
The map stores each element as a key with a boolean value to quickly check if it appeared before.
Step 2: Append only new elements
When an element is not in the map, it is added to the result slice to keep only unique values.
Step 3: Return the unique slice
After processing all elements, the result slice contains no duplicates and is returned.
Alternative Approaches
package main import ( "fmt" "sort" ) func removeDuplicatesSorted(slice []int) []int { if len(slice) == 0 { return slice } sort.Ints(slice) j := 0 for i := 1; i < len(slice); i++ { if slice[j] != slice[i] { j++ slice[j] = slice[i] } } return slice[:j+1] } func main() { nums := []int{4, 2, 2, 3, 1, 4, 5} unique := removeDuplicatesSorted(nums) fmt.Println(unique) }
package main import "fmt" func removeDuplicates(slice []int) []int { seen := make(map[int]struct{}) var result []int for _, v := range slice { if _, ok := seen[v]; !ok { seen[v] = struct{}{} result = append(result, v) } } return result } func main() { nums := []int{1, 2, 2, 3, 4, 4, 5} unique := removeDuplicates(nums) fmt.Println(unique) }
Complexity: O(n) time, O(n) space
Time Complexity
The program loops through the slice once, checking and inserting elements into a map, which is O(1) on average, so total time is O(n).
Space Complexity
The map and result slice grow with the number of unique elements, so space is O(n) in the worst case.
Which Approach is Fastest?
Using a map is fastest for unsorted slices. Sorting first can reduce space but adds O(n log n) time.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Map to track seen | O(n) | O(n) | Unsorted slices, preserves order |
| Sort and remove in place | O(n log n) | O(1) | When order can change and space is limited |
| Map with struct{}{} | O(n) | O(n) | Memory-efficient map usage |