2021-12-15 每日打卡:难题精刷

本文分享了一篇关于使用Python解决LeetCode中等和困难难度题目的博客,重点介绍了如何通过极角转换处理坐标和角度,确保在处理跨越二三象限的夹角时不遗漏情况。作者强调保持初学者的热情和专注对于编程能力提升的重要性,并提供了两种不同的解决方案:一种是使用二分查找法,另一种是滑动窗口法。同时,博客还涉及了atan2函数的使用细节和代码实现。
摘要由CSDN通过智能技术生成

2021-12-15 每日打卡:难题精刷

写在前面

“这些事儿在熟练之后,也许就像喝口水一样平淡,但却能给初学者带来巨大的快乐,我一直觉得,能否始终保持如初学者般的热情、专注,决定了在做某件事时能走多远,能做多好。” 该系列文章由python编写,所刷题目共三个来源:之前没做出来的 ;Leetcode中等,困难难度题目; 周赛题目;某个专题的经典题目,所有代码已AC。每日1-3道,随缘剖析,希望风雨无阻,作为勉励自己坚持刷题的记录。

1610. 可见点的最大数目

在这里插入图片描述在这里插入图片描述

  • 首先把坐标和角度关系统一,这里使用极角转换:
    • 使用反三角函数,范围最多只能覆盖 π \pi π,需要坐标判断
    • 使用库函数atan2请添加图片描述
      这个库函数的范围是 [ − π , π ] [-\pi,\pi] [π,π],但是我们可以通过符号加2 π \pi π转换一下,最终范围如下图:
      在这里插入图片描述

注意,这道题的难度在于一些细节:

  • atan2函数的返回值是弧度制的角度,所以degree也需要改变!
  • 如果直接使用返回值问题,会漏掉夹角横跨二三象限的情况,也就是 − π -\pi π π \pi π这段距离是断掉的,因为此时坐标并不连续。所以我们期望把 − π -\pi π的坐标加上2 π \pi π使得这一块坐标连续,而检查时需要检查的是- π \pi π π \pi π加上转化后的部分,所以遍历的范围一定要注意,是还未转化的数组长度!直接添加到数组中的原因是因为- π \pi π的位置正好在排序后放在第一位,也是接下来该排的位置。
  • 可以选择滑动数组or二分法的方法快速检查:
class Solution:
    def visiblePoints(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]

        degree = angle * pi / 180
        maxCnt = max((bisect_right(polarDegrees, polarDegrees[i] + degree) - i for i in range(n)), default=0)
        return maxCnt + sameCnt

  • 滑动窗口的方法:
class Solution:
    def visiblePoints(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]

        right = 0
        maxCnt = 0
        degree = angle * pi / 180
        for i in range(n):
            # right = 0,这一句放在这里会超时,相当于On2了,滑动窗口的精髓在于前面的窗口边界可以重复使用!
            while polarDegrees[right] <= polarDegrees[i] + degree:
                right += 1
            maxCnt = max(maxCnt, right - i)
        return sameCnt + maxCnt
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要找出某个日期的正确上下班打卡时间,你可以使用`datetime`模块进行日期时间的比较和筛选。下面是一个示例代码: ```python import datetime # 打卡数据 data = [ {'日期': '2023-06-10', '开始时间': '2023-06-10 16:27:00', '结束时间': '2023-06-10 17:39:00'}, {'日期': '2023-06-11', '开始时间': '2023-06-11 01:57:00', '结束时间': '2023-06-11 02:02:00'}, {'日期': '2023-06-11', '开始时间': '2023-06-11 15:57:00', '结束时间': '2023-06-12 01:51:00'}, {'日期': '2023-07-01', '开始时间': '2023-07-01 08:09:00', '结束时间': '2023-07-01 17:25:00'}, {'日期': '2023-07-01', '开始时间': '2023-07-01 17:32:00', '结束时间': '2023-07-01 17:41:00'} ] target_date = datetime.date(2023, 6, 11) # 指定目标日期 # 遍历打卡数据,找到目标日期的打卡记录 for record in data: record_date = datetime.datetime.strptime(record['日期'], '%Y-%m-%d').date() if record_date == target_date: start_time = datetime.datetime.strptime(record['开始时间'], '%Y-%m-%d %H:%M:%S') end_time = datetime.datetime.strptime(record['结束时间'], '%Y-%m-%d %H:%M:%S') print('开始时间:', start_time) print('结束时间:', end_time) ``` 在上面的示例代码中,我们首先指定目标日期为`2023-06-11`,然后遍历打卡数据,找到与目标日期匹配的记录。然后将开始时间和结束时间转换为`datetime`对象,并打印出来。 你可以根据实际需要修改目标日期和打卡数据,以适应你的情况。 希望对你有所帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值