【Leetcode】1610. Maximum Number of Visible Points

题目地址:

https://leetcode.com/problems/maximum-number-of-visible-points/

给定平面直角坐标系的 n n n个点,再给定一个角度 a a a(范围 [ 0 , 360 ) [0,360) [0,360)),给定一个观察点,问该观察点张开角度 a a a最多能看到多少个点。有可能某个点恰好与观察点重合。

先求一下每个点与 x x x正方向所夹的角,可以用 arccos ⁡ \arccos arccos来求,然后标准化一下(取 [ 0 , 2 π ) [0,2\pi) [0,2π)范围内),接着排序,由于张开的范围可能横跨 2 π 2\pi 2π,所以可以开个 2 n 2n 2n的数组循环存储,后面 n n n个点的角度增加 2 π 2\pi 2π。最后滑动窗口求一下最多能看到多少个点。代码如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {
    public int visiblePoints(List<List<Integer>> points, int angle, List<Integer> location) {
        int cnt = 0;
        double x = location.get(0), y = location.get(1);
        List<Double> list = new ArrayList<>();
        for (List<Integer> point : points) {
        	// 记录一下重合的
            if (point.equals(location)) {
                cnt++;
                continue;
            }
            
            double x1 = point.get(0), y1 = point.get(1);
            double acos = Math.acos((x1 - x) / Math.sqrt(pow2(x1 - x) + pow2(y1 - y)));
            if (y1 < y) {
                acos = 2 * Math.PI - acos;
            }
            list.add(acos);
        }
        
        double ang = angle / 180.0 * Math.PI;
        list.sort(Double::compare);
        int size = list.size();
        for (int i = size; i < size * 2; i++) {
            list.add(list.get(i - size) + 2 * Math.PI);
        }
        
        int res = cnt;
        for (int i = 0, j = 0; i < list.size(); i++) {
            while (j < list.size() && list.get(j) - list.get(i) <= ang) {
                j++;
            }
            
            res = Math.max(res, cnt + j - i);
        }
        
        return res;
    }
    
    double pow2(double x) {
        return x * x;
    }
}

时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn),空间 O ( n ) O(n) O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值