栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

LeetCode——1610.可见点的最大数目

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LeetCode——1610.可见点的最大数目

通过万岁!!!

  • 题目:就是给你一个点,然后给你一个角度(也就是视野的角度angle)。可以在这个点上转动,但不能移动。看看周围的点,最多多少个出现在你的视野中。点都是在平面直角坐标系上的,给出一个二维数组,数组中就是点的横坐标和纵坐标。
  • 思路:也就是说,我们的角度是angle,角有两条边我们转动起始边即可。可以想到一种类似滑动窗口,我们的窗口大小是固定的,然后看里面最多能出现多少个点。那我们以角度为单位,将目标点的角度计算出现。
  • 注意:这里题目中有几个比较坑。就是自己所占的点,也可能是目标点。
  • 技巧:
    • 首先是将角度计算出来,然后存到一个数组中,这里需要对这个数组进行排序的。
    • 其次,滑动窗口其实就是两个指针,我们left从0开始,然后right进行++,++的前提是指向的角度要小于我们的视野角,否则让left++。
    • 然后就是java中的,java的arctan公式,也就是atan2()计算出来的结果不是0到360,而是0到2PI。而给出的angle是角度0到360的形式。
    • 并且,因为我们的角度是0到2PI,所以我们还需要考虑当left转动一圈后快要到达2PI的时候,因为到达2PI就是一圈了,我们就可以停止了。这时候我们可以对数组进行补全。也就是说,我们计算出来的角度小于angle的时候,需要将这些点+2PI。当然,可以直接将数组复制一分,添加到后面,但是空间复杂度会略高。

伪代码

定义一个自己所在的点loc
定义目标点角度的数组angles
遍历目标点,计算点的角度
    如果是自己所在点,loc++,并且continue。
    计算角度值目标点与所占点之间的角度。并添加到angles中。
angles数组进行排序
遍历angles数组,将小于angle的元素+2PI后添加到数组中。(这里只能用fori的循环遍历,并且条件是小于angles.size(),而这个值必须要提前存储,否则添加元素数组就变了,这样会报并发错误)
定义max,用来存储最大的点数。
双指针遍历数组,条件是right要小于angles的长度
    如果,right指向的角度-left指向的角度小于视野角,那么right++
    否则,取right-left和max的最大值。并且left++
return loc+max;

java代码

class Solution {
    public int visiblePoints(List> points, int angle, List location) {
        int loc = 0;// 自己所在点,也是可以检测到的
        ArrayList angles = new ArrayList(points.size());
        for (List point : points) {
            if (point.get(0) == location.get(0) && point.get(1) == location.get(1)) {
                loc++;
                continue;
            }
            angles.add(Math.atan2(point.get(0) - location.get(0), point.get(1) - location.get(1)));// 角度,是PI的那种形式
        }
        Collections.sort(angles);
        // 使用双指针遍历angles数组,两个指针之间的距离不能超过angle,让慢指针需要到达360,因此需要将angles中角度小于angle的加上360
        double anglePI = angle * Math.PI / 180;// 将给定的角度转换为PI的形式
        int temp = angles.size();// 这里必须这样使用fori,不然会数组一直遍历不完
        for (int i = 0; i < temp; i++) {
            if (angles.get(i) < anglePI) angles.add(angles.get(i) + 2 * Math.PI);
            else break;
        }
        temp = 0;// 这个就是max
        int left = 0, right = 0;
        while (right < angles.size()) {
            if (angles.get(right) - angles.get(left) <= anglePI) {
                right++;
            } else {
                temp = temp > (right - left) ? temp : right - left;
                left++;
            }
        }
        return temp + loc;
    }
}
  • 总结:这个题技巧性比较强,我们必须要将二维的点,变成一维的角,然后使用滑动窗口。其实滑动窗口就是双指针。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/667011.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号