Your implementation, to me at least, doesn't seem correct. You need to remove adjacent duplicates, but looking at your last example, the sequence acaaabbacdddd
completely removes the b
and d
characters from the slice. You're also using an awful lot of code to do a simple thing. What I'd do is quite simply this:
- Iterate over the slice from index 0 to the next to last character
- For each character, iterate over the remainder of the slice (nested loop) until you find a character that doesn't equal the current index
- For each character at the current position + 1 that matches the current one, remove it, as it's an adjacent duplicate.
The code itself is quite simple:
func dedup(s []string) []string {
// iterate over all characters in slice except the last one
for i := 0; i < len(s)-1;i++ {
// iterate over all the remaining characeters
for j := i+1; j < len(s); j++ {
if s[i] != s[j] {
break // this wasn't a duplicate, move on to the next char
}
// we found a duplicate!
s = append(s[:i], s[j:]...)
}
}
return s
}
Given an input like [g e e k s f o r g e e g]
, the output of this is [g e k s f o r g e g]
Demo
The only trickery here is this line: s = append(s[:i], s[j:]...)
. What this effectively does is reassign the slice s
to contain i
values starting at 0 (so if i
is 2, the slice will be [g, e]
). The second part is creating a slice starting at j
, until the end of s
. Again, if j
is 2, this slice will be all values starting at offset 2 until the end ([e k s f o r g e e g]
).
So let's look at an actual example:
i
== 1j
==i+1
(2)s[i]
==e
,s[j] ==
e`
We have a duplicate, so we'll reassign s
like so:
s = append(s[:1], s[2:]...)`
This means we're appending [e k s f o r g e e g]
to [g]
, removing the duplicate e
. Job done.
Note:
I've used []string
here, but it should go without saying that a slice of characters is probably best represented as either []byte
or []rune
(for full UTF-8 support). Regardless of the type you end up using, the code above will work with with any type that can be compared with the ==
operator