import "sort" type customSort struct { nums []int indices []int } func (c customSort) Len() int { return len(c.nums) } func (c customSort) Swap(i, j int) { c.indices[i], c.indices[j] = c.indices[j], c.indices[i] } func (c customSort) Less(i, j int) bool { oi := c.indices[i] oj := c.indices[j] return c.nums[oi] < c.nums[oj] } func twoSum(nums []int, target int) []int { // Alternate solution: using two stops // Make a slice containing indices to the original array si := make([]int, len(nums)) for i, _ := range nums { si[i] = i } // Sort the slice of indices in ascending order. This hackery // is needed because that's how Go's custom sorting is implemented sort.Sort(customSort{ nums: nums, indices: si, }) lc := 0 rc := len(si) - 1 for lc < rc { // Remember: si[lc] gives me the "index to original slice", // which I can then use to get the left stop's value. Similarly // get the right stop value. l := nums[si[lc]] r := nums[si[rc]] if l+r == target { return []int{si[lc], si[rc]} } // Remember: if this is less, then we need to "increase the value" of // l + r. Since we are traversing in the sorted array, this can only // mean one thing — we increase the left stop if l+r < target { lc++ } else { rc-- } } // If we reach here, basically we didn't find the target return []int{} }