Skip to main content
Back to problems
#1610
Hard Algorithms

Maximum number of visible points

Array Math Geometry Sliding Window Sorting
38.0% acceptance
Feb 25, 2026
625
767
You are given an array points, an integer angle, and your location, where location = [posx, posy] and points[i] = [xi, yi] both denote integral coordinates on the X-Y plane. Initially, you are facing directly east from your position. You cannot move from your position, but you can rotate. In other words, posx and posy cannot be changed. Your field of view in degrees is represented by angle, determining how wide you can see from any given view direction. You can see some set of points if, for each point, the angle formed by the point, your position, and the immediate east direction from your position is in your field of view. There can be multiple points at one coordinate. There may be points at your location, and you can always see these points regardless of your rotation. Points do not obstruct your vision to other points. Return the maximum number of points you can see.

Solution

Rust
Time O(n²)
Space O(n)
LeetCode
solution.rs
impl Solution {
  pub fn visible_points(points: Vec<Vec<i32>>, angle: i32, location: Vec<i32>) -> i32 {
    use std::f64::consts::PI;
    let px = location[0] as f64;
    let py = location[1] as f64;
    let angle_rad = angle as f64 * PI / 180.0;
    let mut at_location = 0i32;
    let mut angles: Vec<f64> = Vec::new();

    for p in &points {
      let dx = p[0] as f64 - px;
      let dy = p[1] as f64 - py;
      if dx == 0.0 && dy == 0.0 {
        at_location += 1;
        continue;
      }
      angles.push(dy.atan2(dx));
    }
    angles.sort_by(|a, b| a.partial_cmp(b).unwrap());
    let n = angles.len();
    // duplicate with offset 2*PI for circular sliding window
    let mut doubled: Vec<f64> = angles.clone();
    for &a in &angles { doubled.push(a + 2.0 * PI); }

    let mut max_in_window = 0usize;
    let mut left = 0usize;
    for right in 0..doubled.len() {
      while doubled[right] - doubled[left] > angle_rad + 1e-9 {
        left += 1;
      }
      let cnt = right - left + 1;
      if right < n || left < n {
        max_in_window = max_in_window.max(cnt);
      }
    }
    at_location + max_in_window as i32
  }
}