第一步,需要将数值的直角坐标,转化为观察点的极坐标,这里直接使用标准库atan2函数,同时注意需要和观察点重合的点剔除掉。
int sameCnt = 0;
vector<double> polarDegrees;
for (auto & point : points) {
if (point[0] == location[0] && point[1] == location[1]) {
sameCnt++;
continue;
}
double degree = atan2(point[1] - location[1], point[0] - location[0]);
polarDegrees.emplace_back(degree);
}
sort(polarDegrees.begin(), polarDegrees.end());
注意到排序后是按照第三象限,第四象限,第一象限,第二象限排序,但这一点不重要。
我们如何找到这个角度,最直接的方法是二分枚举,我们枚举一个起点,再找到start + theta对应的index,这个可以用二分来找。然后记录最大值。
注意,这里需要将角度+2*pi用来覆盖所有结果,完整代码
class Solution {
public:
int visiblePoints(vector<vector<int>>& points, int angle, vector<int>& location) {
int sameCnt = 0;
vector<double> polarDegrees;
for (auto & point : points) {
if (point[0] == location[0] && point[1] == location[1]) {
sameCnt++;
continue;
}
double degree = atan2(point[1] - location[1], point[0] - location[0]);
polarDegrees.emplace_back(degree);
}
sort(polarDegrees.begin(), polarDegrees.end());
int m = polarDegrees.size();
for (int i = 0; i < m; ++i) {
polarDegrees.emplace_back(polarDegrees[i] + 2 * M_PI);
}
int maxCnt = 0;
double degree = angle * M_PI / 180;
for (int i = 0; i < m; i++) {
auto it = upper_bound(polarDegrees.begin() + i, polarDegrees.end(), polarDegrees[i] + degree);
int curr = it - polarDegrees.begin() - i;
maxCnt = max(maxCnt, curr);
}
return maxCnt + sameCnt;
}
};
还有一种方法是直接用双指针枚举,
class Solution {
public:
int visiblePoints(vector<vector<int>>& points, int angle, vector<int>& location) {
int sameCnt = 0;
vector<double> polarDegrees;
for (auto & point : points) {
if (point[0] == location[0] && point[1] == location[1]) {
sameCnt++;
continue;
}
double degree = atan2(point[1] - location[1], point[0] - location[0]);
polarDegrees.emplace_back(degree);
}
sort(polarDegrees.begin(), polarDegrees.end());
int m = polarDegrees.size();
for (int i = 0; i < m; ++i) {
polarDegrees.emplace_back(polarDegrees[i] + 2 * M_PI);
}
int maxCnt = 0;
int right = 0;
double degree = angle * M_PI / 180;
for (int i = 0; i < m; ++i) {
while (right < polarDegrees.size() && polarDegrees[right] <= polarDegrees[i] + degree) {
right++;
}
maxCnt = max(maxCnt, right - i);
}
return maxCnt + sameCnt;
}
};