65 lines
1.3 KiB
Go
65 lines
1.3 KiB
Go
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{}
|
|
} |