973. K Closest Points to Origin
We have a list of points on the plane. Find the K closest points to the origin (0, 0).
(Here, the distance between two points on a plane is the Euclidean distance.)
You may return the answer in any order. The answer is guaranteed to be unique (except for the order that it is in.)
Example 1:
Input: points = [[1,3],[-2,2]], K = 1
Output: [[-2,2]]
Explanation:
The distance between (1, 3) and the origin is sqrt(10).
The distance between (-2, 2) and the origin is sqrt(8).
Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin.
We only want the closest K = 1 points from the origin, so the answer is just [[-2,2]].
Example 2:
Input: points = [[3,3],[5,-1],[-2,4]], K = 2
Output: [[3,3],[-2,4]]
(The answer [[-2,4],[3,3]] would also be accepted.)
Note:
1 <= K <= points.length <= 10000
-10000 < points[i][0] < 10000
-10000 < points[i][1] < 10000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/k-closest-points-to-origin
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Thought and method:
1、Totally Sort
Sort all the distances from the origin, and output the nearest K points. It is most easiest to think of and transfer it into codes.However, it perfomance bad in the time consume due to the need in sorting.
Time complexity: O(nlogn)
Space complexity: O(n)
2、divide-and-conquer method
Condering that the first process to influence the time complexity is the sorting, we mainly do some change in decreasing the numbers which we have to send into the sorting.
We randomly select an element x and divide the array into two parts: one that is less than x from the origin, and one that is greater than x from the origin. Thus we can reduce the size of the problem by half each time.
We can have a function called Work that does partial quicksort by selecting a random element pos as the tag and then using this element to divide the array into two parts.
Then, we have two parts [i, pos] and [pos+1, j]
if K < pos, we just call work on the first part.
If K >pos, then the first part needs to be selected, we need to call work on the second part.
average Time complexity: O(n)
Space complexity: O(n)
code
1、
we do not need to also calculate the square root of the value, the square of the value is enough.
func kClosest(points [][]int, K int) [][]int {
sort.Slice(points, func(i, j int) bool{
return float64(points[i][0]*points[i][0] + points[i][1]*points[i][1]) < float64(points[j][0]*points[j][0] + points[j][1]*points[j][1])
})
return points[:K]
}
2、At the beginning of this section, I was influenced by the official documents.
"random element" "Part of the sort"and also "using two pointer"
After a number of failures, I realized that using the exact same idea would not work in GO, given that the use of including Pointers is not as flexible as it is in Java and Python.
After consulting the following sources, I realized that using only a pointer to an array is better than two pointer with hard and complex calclulating and codes.
link.
func kClosest(points [][]int, K int) [][]int {
result := [][]int{}
kClosestHelper(points,K,&result)
return result
}
func kClosestHelper(points [][]int, K int,result *[][]int) *[][]int {
start,end := 0,len(points)-1
pos := work(points,start,end)
//pos is the sign
//pos < K-1 consider the whole left part of pos and part of points in the right part
if pos < K-1 {
*result = append(*result,points[:pos+1]...)
return kClosestHelper(points[pos+1:],K-pos-1,result)
}
//consider the only left part of pos
if pos > K-1{
return kClosestHelper(points[:pos],K,result)
}
//else result
*result = append(*result,points[:pos+1]...)
return result
}
//part quick sort
func work(nums [][]int, start,end int) int{
pos,left,right := nums[start],start,end
for (left < right){
for (distance(nums[right]) >= distance(pos) && left<right) {
right--
}
for (distance(nums[left]) <= distance(pos) && left<right) {
left++
}
nums[left],nums[right] = nums[right],nums[left]
}
nums[start],nums[left] = nums[left],nums[start]
return left
}
//calculate
func distance(num []int)int{
return num[0] * num[0] + num[1] * num[1]
}
test
Example 1:
Input: points = [[1,3],[-2,2]], K = 1
Example 2:
Input: points = [[3,3],[5,-1],[-2,4]], K = 2
As you can see that the former way is running much slower than the latters.