这次是Lintcode的题目:http://www.lintcode.com/zh-cn/problem/subarray-sum-closest/
给一个数组和k,找出一个子数组,和最接近k,如果有多个返回任意一个。
当然n平方肯定可以解决,但是额外使用空间可以Onlogn。
思路还是用S(i)-S(j)的方式。
先计算出全部的s(i),然后存入map,key是sum,value是最后一个元素的位置。
接着再按照sum排序,然后遍历一次sum,这是只需要判断前后连着的两个sum只差即可,找出最接近k的。
下面是go代码:
package main
import (
"fmt"
"sort"
)
type P struct{
sum, index int
}
type PList []*P
func (list PList) Len() int{
return len(list)
}
func (list PList) Less(i, j int) bool{
return list[i].sum < list[j].sum
}
func (list PList) Swap(i, j int){
list[i], list[j] = list[j], list[i]
}
func abs(x int) int{
if x >= 0{
return x
}
return -x
}
func subarraySum(nums []int, k int) (int, int) {
sum := 0
list := PList{}
p := new(P)
p.sum = 0
p.index = -1
list=append(list, p)
for i,v := range nums{
sum += v
p := new(P)
p.sum = sum
p.index = i
list=append(list, p)
}
sort.Sort(list)
min, f, b:= 1000000, 0, 0
for i,v := range list{
if i==0 {
continue
}
cur := abs(v.sum - list[i-1].sum - k)
if cur < min{
min = cur
f = list[i-1].index - 1
b = list[i].index
}
}
return f,b
}
func main() {
array := []int{-3, 1, 1, -3, 5}
k := 0
f, b := subarraySum(array, k)
fmt.Println(f, b)
}