Golang — Leetcode 973. K Closest Points to Origin

题意就不说了,leetcode 上都有。

这道题首先想到的是将距离算出来sort后取前K(好像这样也能过),后来又想到了前一阵子刚看的快速选择,经过选择挑好第K大的值时,K即是值也是索引,所以索引K前的便是前K个最小距离。相比于快排能够少排后半部分节省时间。

刚开始想到这样做的时候直接上手就开始写了,当时用一个map存储距离(key)和点(value)的关系,但是发现距离重复的情况下会有覆盖的情况([-1,1]和[1,-1]距离都是2),又想到把key-value反过来存储,好嘛踩坑了key不能存储slice(基础不行啊,因为之前一直用C++,思路还没转过来,C++中的multiset或者unordered_map<pair<int, int>, int>解决了),最后决定map存储原points每个point的索引(key)和距离(value),通过快速选择把距离最小的K个points索引选出来,放到返回切片里返回。

结果好像还可以,潜意识里觉得不用这样做有更好的方法,但是不想细琢磨了,今天也是个lazyboy。

执行用时 : 928 ms, 在K Closest Points to Origin的Go提交中击败了92.86% 的用户
内存消耗 : 65.6 MB, 在K Closest Points to Origin的Go提交中击败了100.00% 的用户
func kClosest(points [][]int, K int) [][]int {
    if len(points) == K {
        return points
    }
    var v []int
    var re [][]int
    m := make(map[int]int)
    for i:=0;i<len(points);i++ {
        m[i] = points[i][0]*points[i][0] + points[i][1]*points[i][1]
        v = append(v, i)
    }
    findK(m, v, 0, len(v)-1, K)
    for i:=0;i<K;i++ {
        re = append(re, points[v[i]])
    }
    return re;
}

func findK(m map[int]int, s []int, start, end, k int) {
    p := m[s[end]]
    l := start
    for i:=start; i<end; i++ {
        if m[s[i]] < p {
            s[l], s[i] = s[i], s[l]
            l++
        }
    }
    s[l], s[end] = s[end], s[l]
    if k == l {
        return
    } else if l < k {
        findK(m, s, l+1, end, k)
    } else {
        findK(m, s, start, l-1, k)
    }
}

记录每天解决的一点小问题,积累起来就能解决大问题。  

猜你喜欢

转载自blog.csdn.net/Lazyboy_/article/details/88416142