力扣每日一题2021-12-16困难题:可见点的最大数目

这篇博客介绍了如何解决计算机科学中的一道题目——1610.可见点的最大数目。通过以给定位置为原点,计算每个点与原点之间的角度,并利用双指针滑动窗口策略,确保窗口内点的角度差不超过指定角度,从而找到能覆盖的最多点数。文章提供了Java和Python两种实现方式,并详细解释了思路和代码细节。
摘要由CSDN通过智能技术生成


1610.可见点的最大数目

题目描述

可见点的最大数目


思路

双指针

根据题意,需要求出在施教范围内最多的点的覆盖数。以location为原点,根据点之间的横坐标差和纵坐标差,计算弧度,再把弧度换算成角度。
将得到的点排序,双指针进行滑动窗口,滑窗的限制是最大角减最小角不得大于固定的angle角度。

Java实现

Java实现

class Solution {
    private int base;
    private int x, y;
    public int visiblePoints(List<List<Integer>> points, int angle, List<Integer> location) {
        base = 0; 
        x = location.get(0); 
        y = location.get(1);
        List<Double> angles = new ArrayList<>();
        for(List<Integer> point: points){
            double degree = helper(point);
            if(degree >= 0)
                angles.add(degree);
        }
        Collections.sort(angles);
        int s = angles.size();
        for(int i=0;i<s;i++)
            angles.add(angles.get(i) + 360);
        int ans = 0;
        for(int l=0,r=0;l<angles.size();l++){
            while(r<angles.size() && angles.get(r) - angles.get(l) <= angle)
                r++;
            ans = Math.max(ans, r - l);
        }
        return ans + base;
    }

    private double helper(List<Integer> point){
        int dx = point.get(0) - x, dy = point.get(1) - y;
        if(dx == 0 && dy == 0){
            base += 1;
            return -1.0;
        }
        if(dx == 0)
            return dy > 0 ? 90.0 : 270.0;
        if(dy == 0)
            return dx > 0 ? 0.0 : 180.0;
        if(dx * dy > 0)
            return Math.toDegrees(Math.atan((double)dy/dx))+(dx > 0 ? 0.0 : 180.0);
        return Math.toDegrees(Math.atan(-(double)dx/dy)) + (dy > 0 ? 90.0 : 270.0);
    }
}
Python实现

Python实现

class Solution:
    def visiblePoints(self, points: List[List[int]], angle: int, location: List[int]) -> int:
        self.base = 0
        def helper(point):
            dx, dy = point[0] - location[0], point[1] - location[1]
            if not dx and not dy:
                self.base += 1
                return None
            if not dx:
                return 90 if dy > 0 else 270
            if not dy:
                return 0 if dx > 0 else 180
            if dx * dy > 0:
                return math.degrees(math.atan(dy/dx)) + (0 if dx > 0 else 180)
            return math.degrees(math.atan(-dx/dy)) + (90 if dx < 0 else 270)
        
        angles = []
        for p in points:
            degree = helper(p)
            if degree is not None:
                angles.append(degree)
        angles.sort()
        angles = angles + [360 + a for a in angles]
        l = r = ans = 0
        while l < len(angles):
            while r < len(angles) and angles[r] - angles[l] <= angle:
                r += 1
            ans = max(ans, r - l)
            l += 1
        return ans + self.base
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值