Infrastructure Go daemon
SECTION 12.2

Two Pointers

Two pointers work on sorted data or when you need to compare elements from different positions.

1 · Before you read — commit to an answer
nums := []int{1, 1, 2, 3, 3}
slow := 0
for fast := 1; fast < len(nums); fast++ {
    if nums[fast] != nums[slow] {
        slow++
        nums[slow] = nums[fast]
    }
}
fmt.Println(slow+1, nums)

Wrong is fine — the in-place section below walks through exactly this loop.

Merging Sorted Lists

Merging sorted log files — classic interview question:

// Merge two sorted slices of timestamps
func mergeSorted(a, b []int) []int {
    result := make([]int, 0, len(a)+len(b))
    i, j := 0, 0
    for i < len(a) && j < len(b) {
        if a[i] <= b[j] {
            result = append(result, a[i])
            i++
        } else {
            result = append(result, b[j])
            j++
        }
    }
    result = append(result, a[i:]...)
    result = append(result, b[j:]...)
    return result
}

O(n+m) time, single pass through both lists.

Removing Duplicates In Place

2 · Worked example — read every step
// Remove duplicate consecutive entries from sorted slice
func removeDuplicates(nums []int) int {
    if len(nums) == 0 {
        return 0
    }
    slow := 0
    for fast := 1; fast < len(nums); fast++ {
        if nums[fast] != nums[slow] {
            slow++
            nums[slow] = nums[fast]
        }
    }
    return slow + 1 // new length
}

The slow pointer marks where to write. The fast pointer scans ahead. O(n) time, O(1) extra space. That's why the pretest slice still ends 3 3 3 — nothing past the new length is ever cleaned up.

Finding Pairs in Sorted Data

// Find two server capacities that sum to target (sorted input)
func twoSumSorted(capacities []int, target int) (int, int) {
    left, right := 0, len(capacities)-1
    for left < right {
        sum := capacities[left] + capacities[right]
        if sum == target {
            return left, right
        } else if sum < target {
            left++ // need a bigger number
        } else {
            right-- // need a smaller number
        }
    }
    return -1, -1
}

O(n) instead of O(n²). Only works on sorted data.

3 · Fill the gaps
Merge two sorted log streams into one — advance only the pointer you copied from, then drain whatever is left.
result := make([]int, 0, len(a)+len(b))
i, j := 0, 0
for i < len(a) &&  {
    if a[i] <= b[j] {
        result = append(result, a[i])
        
    } else {
        result = append(result, b[j])
        
    }
}
result = append(result, ...)
result = append(result, b[j:]...)
return result

The loop stops as soon as either stream runs dry; the two final appends drain the survivor (one of them is a no-op).

4 · From scratch — this feeds your review queue