publicclassSolution { publicintVisiblePoints(IList<IList<int>> points, int angle, IList<int> location) { int sameCnt = 0; List<double> polarDegrees = new List<double>(); int locationX = location[0]; int locationY = location[1]; for (int i = 0; i < points.Count; ++i) { int x = points[i][0]; int y = points[i][1]; if (x == locationX && y == locationY) { sameCnt++; continue; } double degree = Math.Atan2(y - locationY, x - locationX); polarDegrees.Add(degree); } polarDegrees.Sort();
int m = polarDegrees.Count; for (int i = 0; i < m; ++i) { polarDegrees.Add(polarDegrees[i] + 2 * Math.PI); }
int maxCnt = 0; double toDegree = angle * Math.PI / 180.0; for (int i = 0; i < m; ++i) { int iteration = BinarySearch(polarDegrees, polarDegrees[i] + toDegree, false); maxCnt = Math.Max(maxCnt, iteration - i); } return maxCnt + sameCnt; }
publicintBinarySearch(List<double> nums, double target, bool lower) { int left = 0, right = nums.Count - 1; int ans = nums.Count; while (left <= right) { int mid = (left + right) / 2; if (nums[mid] > target || (lower && nums[mid] >= target)) { right = mid - 1; ans = mid; } else { left = mid + 1; } } return ans; } }
var visiblePoints = function(points, angle, location) { let sameCnt = 0; const polarDegrees = []; let locationX = location[0]; let locationY = location[1]; for (let i = 0; i < points.length; ++i) { const x = points[i][0]; const y = points[i][1]; if (x === locationX && y === locationY) { sameCnt++; continue; } const degree = Math.atan2(y - locationY, x - locationX); polarDegrees.push(degree); } polarDegrees.sort((a, b) => a - b);
const m = polarDegrees.length; for (let i = 0; i < m; ++i) { polarDegrees.push(polarDegrees[i] + Math.PI * 2); }
let maxCnt = 0; const toDegree = angle * Math.PI / 180; for (let i = 0; i < m; ++i) { const iteration = binarySearch(polarDegrees, polarDegrees[i] + toDegree, false); maxCnt = Math.max(maxCnt, iteration - i); } return maxCnt + sameCnt; };
constbinarySearch = (nums, target, lower) => { let left = 0, right = nums.length - 1; let ans = nums.length; while (left <= right) { const mid = Math.floor((left + right) / 2); if (nums[mid] > target || (lower && nums[mid] >= target)) { right = mid - 1; ans = mid; } else { left = mid + 1; } } return ans; }
publicclassSolution { publicintVisiblePoints(IList<IList<int>> points, int angle, IList<int> location) { int sameCnt = 0; List<double> polarDegrees = new List<double>(); int locationX = location[0]; int locationY = location[1]; for (int i = 0; i < points.Count; ++i) { int x = points[i][0]; int y = points[i][1]; if (x == locationX && y == locationY) { sameCnt++; continue; } double degree = Math.Atan2(y - locationY, x - locationX); polarDegrees.Add(degree); } polarDegrees.Sort(); int m = polarDegrees.Count; for (int i = 0; i < m; ++i) { polarDegrees.Add(polarDegrees[i] + 2 * Math.PI); }
int maxCnt = 0; int right = 0; double toDegree = angle * Math.PI / 180; for (int i = 0; i < m; ++i) { double curr = polarDegrees[i] + toDegree; while (right < polarDegrees.Count && polarDegrees[right] <= curr) { right++; } maxCnt = Math.Max(maxCnt, right - i); } return maxCnt + sameCnt; } }
var visiblePoints = function(points, angle, location) { let sameCnt = 0; const polarDegrees = []; let locationX = location[0]; let locationY = location[1]; for (let i = 0; i < points.length; ++i) { const x = points[i][0]; const y = points[i][1]; if (x === locationX && y === locationY) { sameCnt++; continue; } const degree = Math.atan2(y - locationY, x - locationX); polarDegrees.push(degree); } polarDegrees.sort((a, b) => a - b);
const m = polarDegrees.length; for (let i = 0; i < m; ++i) { polarDegrees.push(polarDegrees[i] + 2 * Math.PI); }
let maxCnt = 0; let right = 0; const toDegree = angle * Math.PI / 180; for (let i = 0; i < m; ++i) { const curr = polarDegrees[i] + toDegree; while (right < polarDegrees.length && polarDegrees[right] <= curr) { right++; } maxCnt = Math.max(maxCnt, right - i); } return maxCnt + sameCnt; };
classSolution: defvisiblePoints(self, points: List[List[int]], angle: int, location: List[int]) -> int: sameCnt = 0 polarDegrees = [] for p in points: if p == location: sameCnt += 1 else: polarDegrees.append(atan2(p[1] - location[1], p[0] - location[0])) polarDegrees.sort()
n = len(polarDegrees) polarDegrees += [deg + 2 * pi for deg in polarDegrees]
maxCnt = 0 right = 0 degree = angle * pi / 180 for i inrange(n): while right < n * 2and polarDegrees[right] <= polarDegrees[i] + degree: right += 1 maxCnt = max(maxCnt, right - i) return sameCnt + maxCnt
复杂度分析
时间复杂度:O(n \log n),其中 n 为坐标的个数,由于需要对所有的极角进行排序,利用移动指针区间查找的时间复杂度为 O(2n + 2n),因此总的时间复杂度应该为 O(n \log n + 2n + 2n) = O(n \log n)。