Advanced Slice Manipulation Techniques in Go

Lesson Overview

Welcome to a key lesson in your technical preparation with Go. In this lesson, we'll delve into Advanced Slice Manipulation Techniques in Go, focusing on the direct representation and manipulation of slices without relying on built-in high-level functions. Understanding this concept is vital for tackling complex algorithmic problems that necessitate custom manipulation of slices.

In-Place Modification

Before we jump into our example, let's quickly cover In-Place Modification with slices. In Go, in-place modification refers to changing elements within a slice directly, without the need for additional memory allocation for another slice. This is advantageous as it conserves memory and can lead to performance improvements. In Go, slices have a dynamic size, but they are backed by an array that determines the capacity. Modifying a slice in place means working directly with the underlying array elements.

Slice Rotation In-Place

A common interview problem involves rotating a slice by k positions. Given a slice nums, the task is to "rotate" it to the right by k positions. This action implies shifting each element to the right and wrapping elements that exceed the slice's length back to the start. For instance, rotating the slice [1, 2, 3, 4, 5, 6, 7] to the right by 3 positions results in [5, 6, 7, 1, 2, 3, 4].

Unlike creating a new slice and copying elements, our challenge is to accomplish this rotation in-place without forming a new slice. We'll employ a three-step slice reversal method to achieve this goal efficiently in Go.

  1. Adjust k to be within bounds: Compute k = k % n to ensure k is within [0, n-1], where n is the length of the slice. This step handles cases where k exceeds n.

  2. Reverse the entire slice: Reversing the complete slice repositions the last k elements to the front in reverse order.

  3. Reverse the first k elements: Reversing these k elements restores their order as needed.

  4. Reverse the remaining elements: Finally, reverse the elements from position k onward to restore their original ordering.

Let's put this into practice:

package main

import (
    "fmt"
)

func rotateSlice(nums []int, k int) {
    n := len(nums)
    if n == 0 {
        return
    }
    
    k = k % n // Ensure k is within the bounds of the slice length

    // Reverse entire slice
    reverse(nums, 0, n-1)
    // Reverse first k elements
    reverse(nums, 0, k-1)
    // Reverse remaining elements
    reverse(nums, k, n-1)
}

// Helper function to reverse a sub-slice
func reverse(nums []int, start int, end int) {
    for start < end {
        nums[start], nums[end] = nums[end], nums[start]
        start++
        end--
    }
}

// Example
func main() {
    nums := []int{1, 2, 3, 4, 5, 6, 7}
    k := 3

    rotateSlice(nums, k)

    for _, num := range nums {
        fmt.Print(num, " ")
    }
    // Output: 5 6 7 1 2 3 4
}
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal