doocs/leetcode 几何算法

doocs/leetcode 几何算法

【免费下载链接】leetcode 🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解 【免费下载链接】leetcode 项目地址: https://gitcode.com/doocs/leetcode

还在为LeetCode几何算法题目头疼吗?一文带你掌握doocs/leetcode中几何算法的核心解题技巧!本文将深入解析三个经典几何算法题目:矩形面积II、直线上最多的点数、矩形面积,通过详细的代码示例、流程图和表格对比,让你彻底理解几何算法的精髓。

📊 几何算法概述

几何算法是计算机科学中处理几何图形和空间关系的重要分支,在LeetCode中主要涉及点、线、面等基本几何元素的计算和处理。doocs/leetcode项目提供了丰富的几何算法题解,涵盖了从简单到困难的各类几何问题。

几何算法核心概念

概念描述应用场景
点(Point)二维平面上的坐标位置判断点是否在直线上、计算点之间的距离
线(Line)由两点确定的直线判断多点共线、计算直线交点
面(Plane)由边界确定的二维区域计算矩形面积、判断区域重叠
向量(Vector)有方向和大小的量计算斜率、判断方向关系

🔢 850. 矩形面积 II

问题描述

给定多个轴对齐的矩形,计算它们覆盖的总面积。任何被两个或多个矩形覆盖的区域应只计算一次。

算法思路

mermaid

核心代码实现

class Node:
    def __init__(self):
        self.l = self.r = 0
        self.cnt = self.length = 0

class SegmentTree:
    def __init__(self, nums):
        n = len(nums) - 1
        self.nums = nums
        self.tr = [Node() for _ in range(n << 2)]
        self.build(1, 0, n - 1)
    
    def build(self, u, l, r):
        self.tr[u].l, self.tr[u].r = l, r
        if l != r:
            mid = (l + r) >> 1
            self.build(u << 1, l, mid)
            self.build(u << 1 | 1, mid + 1, r)
    
    def modify(self, u, l, r, k):
        if self.tr[u].l >= l and self.tr[u].r <= r:
            self.tr[u].cnt += k
        else:
            mid = (self.tr[u].l + self.tr[u].r) >> 1
            if l <= mid:
                self.modify(u << 1, l, r, k)
            if r > mid:
                self.modify(u << 1 | 1, l, r, k)
        self.pushup(u)
    
    def pushup(self, u):
        if self.tr[u].cnt:
            self.tr[u].length = self.nums[self.tr[u].r + 1] - self.nums[self.tr[u].l]
        elif self.tr[u].l == self.tr[u].r:
            self.tr[u].length = 0
        else:
            self.tr[u].length = self.tr[u << 1].length + self.tr[u << 1 | 1].length

class Solution:
    def rectangleArea(self, rectangles: List[List[int]]) -> int:
        segs = []
        alls = set()
        for x1, y1, x2, y2 in rectangles:
            segs.append((x1, y1, y2, 1))
            segs.append((x2, y1, y2, -1))
            alls.update([y1, y2])
        
        segs.sort()
        alls = sorted(alls)
        tree = SegmentTree(alls)
        m = {v: i for i, v in enumerate(alls)}
        ans = 0
        for i, (x, y1, y2, k) in enumerate(segs):
            if i:
                ans += tree.length * (x - segs[i - 1][0])
            tree.modify(1, m[y1], m[y2] - 1, k)
        ans %= int(1e9 + 7)
        return ans

复杂度分析

操作时间复杂度空间复杂度
排序y坐标O(n log n)O(n)
构建线段树O(n)O(n)
扫描线处理O(n log n)O(1)
总计O(n log n)O(n)

📈 149. 直线上最多的点数

问题描述

给定一个点集,求最多有多少个点在同一条直线上。

算法思路

mermaid

核心代码实现

class Solution:
    def maxPoints(self, points: List[List[int]]) -> int:
        def gcd(a, b):
            return a if b == 0 else gcd(b, a % b)
        
        n = len(points)
        ans = 1
        for i in range(n):
            x1, y1 = points[i]
            cnt = Counter()
            for j in range(i + 1, n):
                x2, y2 = points[j]
                dx, dy = x2 - x1, y2 - y1
                g = gcd(dx, dy)
                k = (dx // g, dy // g)
                cnt[k] += 1
                ans = max(ans, cnt[k] + 1)
        return ans

斜率处理技巧

为了避免浮点数精度问题,我们使用最简分数形式表示斜率:

mermaid

复杂度分析

方法时间复杂度空间复杂度优点缺点
暴力枚举O(n³)O(1)简单直观效率低
哈希表优化O(n² log m)O(n)效率较高需要处理精度问题

🟦 223. 矩形面积

问题描述

计算两个轴对齐矩形的覆盖总面积,需要考虑重叠区域。

算法思路

mermaid

核心代码实现

class Solution:
    def computeArea(
        self,
        ax1: int, ay1: int, ax2: int, ay2: int,
        bx1: int, by1: int, bx2: int, by2: int
    ) -> int:
        # 计算两个矩形的面积
        area1 = (ax2 - ax1) * (ay2 - ay1)
        area2 = (bx2 - bx1) * (by2 - by1)
        
        # 计算重叠区域的宽度和高度
        width = min(ax2, bx2) - max(ax1, bx1)
        height = min(ay2, by2) - max(ay1, by1)
        
        # 计算重叠区域面积(如果无重叠则为0)
        overlap = max(width, 0) * max(height, 0)
        
        return area1 + area2 - overlap

重叠区域计算原理

mermaid

边界情况处理

情况描述处理方式
无重叠width或height为负数max(0, value)
完全包含一个矩形完全在另一个内部正常计算重叠区域
边接触矩形边重合但无面积重叠width或height为0

📋 几何算法解题技巧总结

1. 坐标处理技巧

# 计算两点间距离
def distance(x1, y1, x2, y2):
    return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)

# 计算向量叉积(判断方向)
def cross_product(x1, y1, x2, y2):
    return x1 * y2 - x2 * y1

# 计算点积(判断夹角)
def dot_product(x1, y1, x2, y2):
    return x1 * x2 + y1 * y2

2. 常见几何问题分类

问题类型典型题目解决思路
点线关系149.直线上最多的点数斜率统计、向量共线
面积计算223.矩形面积、850.矩形面积II扫描线、线段树
相交判断836.矩形重叠边界比较、投影分析
最近点对经典问题分治法、平面扫描

3. 精度处理建议

# 使用分数避免浮点误差
from fractions import Fraction

# 或者使用最大公约数标准化
def normalize_slope(dx, dy):
    if dx == 0 and dy == 0:
        return (0, 0)
    if dx == 0:
        return (0, 1)
    if dy == 0:
        return (1, 0)
    
    g = math.gcd(abs(dx), abs(dy))
    if dx < 0:  # 统一让dx为正
        dx, dy = -dx, -dy
    return (dx // g, dy // g)

🚀 实战演练

练习题目推荐

  1. 简单级别

      1. 矩形面积 - 掌握基本重叠区域计算
      1. 矩形重叠 - 判断矩形是否相交
  2. 中等级别

      1. 直线上最多的点数 - 斜率统计与精度处理
      1. 安装栅栏 - 凸包算法应用
  3. 困难级别

      1. 矩形面积 II - 扫描线与线段树
      1. 完美矩形 - 复杂区域覆盖判断

学习路径建议

mermaid

💡 总结

通过本文的学习,你应该已经掌握了doocs/leetcode中几何算法的核心解题技巧:

  1. 矩形面积计算:理解重叠区域的处理方法,掌握扫描线算法和线段树的应用
  2. 点线关系分析:学会使用哈希表统计斜率,避免浮点数精度问题
  3. 算法优化思路:从暴力解法到优化解法的演进路径

几何算法虽然看似复杂,但只要掌握核心的数学原理和数据结构应用,就能有效解决各类几何问题。建议多练习相关题目,培养空间思维能力,在实际编程中注意处理边界情况和精度问题。

继续深入学习可以探索计算几何的更多领域,如凸包算法、最近点对问题、多边形处理等,这些知识在图形学、GIS系统、游戏开发等领域都有广泛应用。

【免费下载链接】leetcode 🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解 【免费下载链接】leetcode 项目地址: https://gitcode.com/doocs/leetcode

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值