题目

最接近原点的的K个点

最接近原点的的K个点

973. 最接近原点的 K 个点

我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。

(这里,平面上两点之间的距离是欧几里德距离。)

你可以按任何顺序返回答案。除了点坐标的顺序之外,答案确保是唯一的。

示例 1:

1
2
3
4
5
6
7
输入:points = [[1,3],[-2,2]], K = 1
输出:[[-2,2]]
解释:
(1, 3) 和原点之间的距离为 sqrt(10),
(-2, 2) 和原点之间的距离为 sqrt(8),
由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。
我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]。

示例 2:
1
2
3
输入:points = [[3,3],[5,-1],[-2,4]], K = 2
输出:[[3,3],[-2,4]]
(答案 [[-2,4],[3,3]] 也会被接受。)

代码

1
2
3
4
5
6
7
8
9
class Solution {
public:
vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
sort(points.begin(),points.end(),[](const vector<int>& u, const vector<int>& v){
return u[0] * u[0] + u[1] * u[1] < v[0] * v[0] + v[1] * v[1];
});
return {points.begin(), points.begin() + K};
}
};

下一个排列

31. 下一个排列

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

思路:

注意到下一个排列总是比当前排列要大,除非该排列已经是最大的排列。我们希望找到一种方法,能够找到一个大于当前序列的新序列,且变大的幅度尽可能小。具体地:

我们需要将一个左边的「较小数」与一个右边的「较大数」交换,以能够让当前排列变大,从而得到下一个排列。

同时我们要让这个「较小数」尽量靠右,而「较大数」尽可能小。当交换完成后,「较大数」右边的数需要按照升序重新排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。

以排列 [4,5,2,6,3,1][4,5,2,6,3,1] 为例:

我们能找到的符合条件的一对「较小数」与「较大数」的组合为 22 与 33,满足「较小数」尽量靠右,而「较大数」尽可能小。

当我们完成交换后排列变为 [4,5,3,6,2,1][4,5,3,6,2,1],此时我们可以重排「较小数」右边的序列,序列变为 [4,5,3,1,2,6][4,5,3,1,2,6]。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int i = nums.size() - 2;
while (i >= 0 && nums[i] >= nums[i+1])
i--;
if (i >= 0) {
int j = nums.size() - 1;
while(j >= 0 && nums[i] >= nums [j])
j--;
swap(nums[i],nums[j]);
}
reverse(nums.begin() + i + 1, nums.end());
}
};