当前位置: 首页 > news >正文

Kimi LeetCode 3382. 用点构造面积最大的矩形 II C语言实现

以下是 LeetCode 3382. 用点构造面积最大的矩形 II 的 C 语言实现,采用 线段树 + 坐标离散化,时间复杂度 O(n \log n):

```c
#include <stdlib.h>
#include <string.h>

typedef struct {
int x;
int y;
} Point;

/* 按 x 排序,x 相同按 y 排序 */
int cmp_point(const void *a, const void *b) {
Point *p1 = (Point*)a;
Point *p2 = (Point*)b;
if (p1->x != p2->x) return p1->x - p2->x;
return p1->y - p2->y;
}

int cmp_int(const void *a, const void *b) {
return *(int*)a - *(int*)b;
}

/* 二分查找 y 在离散化数组中的索引 */
int find_idx(int *ys, int n, int y) {
int l = 0, r = n - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (ys[mid] == y) return mid;
if (ys[mid] < y) l = mid + 1;
else r = mid - 1;
}
return -1;
}

/* 不小于 x 的最小 2 的幂 */
int next_pow2(int x) {
int n = 1;
while (n < x) n <<= 1;
return n;
}

/* 迭代式线段树,维护区间最大值 */
typedef struct {
int n; // 扩展为 2 的幂后的大小
int *tree;
} SegTree;

SegTree* seg_tree_create(int size) {
SegTree *st = (SegTree*)malloc(sizeof(SegTree));
st->n = next_pow2(size);
st->tree = (int*)malloc(sizeof(int) * 2 * st->n);
for (int i = 0; i < 2 * st->n; i++) st->tree[i] = -1;
return st;
}

void seg_tree_free(SegTree *st) {
free(st->tree);
free(st);
}

void seg_tree_update(SegTree *st, int pos, int val) {
int i = pos + st->n;
st->tree[i] = val;
for (i >>= 1; i > 0; i >>= 1) {
int left = st->tree[i << 1];
int right = st->tree[(i << 1) | 1];
st->tree[i] = left > right ? left : right;
}
}

/* 查询 [l, r) 区间最大值,左闭右开 */
int seg_tree_query_range(SegTree *st, int l, int r) {
if (l >= r) return -1;
int res = -1;
l += st->n;
r += st->n;
while (l < r) {
if (l & 1) {
if (st->tree[l] > res) res = st->tree[l];
l++;
}
if (r & 1) {
r--;
if (st->tree[r] > res) res = st->tree[r];
}
l >>= 1;
r >>= 1;
}
return res;
}

int seg_tree_query_point(SegTree *st, int pos) {
return st->tree[pos + st->n];
}

/* LeetCode 函数签名 */
long long maxRectangleArea(int* xCoord, int xCoordSize, int* yCoord, int yCoordSize) {
int n = xCoordSize;
Point *points = (Point*)malloc(sizeof(Point) * n);
for (int i = 0; i < n; i++) {
points[i].x = xCoord[i];
points[i].y = yCoord[i];
}

qsort(points, n, sizeof(Point), cmp_point);

/* y 坐标离散化 */
int *ys = (int*)malloc(sizeof(int) * n);
memcpy(ys, yCoord, sizeof(int) * n);
qsort(ys, n, sizeof(int), cmp_int);
int m = 0;
for (int i = 0; i < n; i++) {
if (i == 0 || ys[i] != ys[i-1]) ys[m++] = ys[i];
}

SegTree *st = seg_tree_create(m);
long long ans = -1;

for (int i = 0; i < n - 1; i++) {
int y1_idx = find_idx(ys, m, points[i].y);

/* 相邻两点 x 相同,可能构成矩形右侧边 */
if (points[i].x == points[i+1].x) {
int y2_idx = find_idx(ys, m, points[i+1].y);
int x1 = seg_tree_query_point(st, y1_idx);
int x2 = seg_tree_query_point(st, y2_idx);

/* 左侧两个顶点的 x 坐标必须相同 */
if (x1 != -1 && x2 != -1 && x1 == x2) {
long long h = (long long)points[i+1].y - points[i].y;
long long w = (long long)points[i].x - x1;
long long area = h * w;

/* 检查矩形内部是否无其他点:区间 (y1, y2) 内所有点的 x 均 < x1 */
if (y2_idx - y1_idx <= 1 || seg_tree_query_range(st, y1_idx + 1, y2_idx) < x1) {
if (area > ans) ans = area;
}
}
}

/* 将当前点加入线段树 */
seg_tree_update(st, y1_idx, points[i].x);
}

seg_tree_free(st);
free(points);
free(ys);
return ans;
}
```

关键点说明

要点 说明
排序扫描 按 `x` 排序后从小到大扫描,保证已处理点都在当前点左侧
离散化 `qsort` + 去重后用二分查找(`bsearch` 手动实现)将 `y` 映射到索引
线段树 迭代式实现,将大小扩展至最近的 2 的幂,确保区间查询正确性
区间查询 采用左闭右开 `[l, r)` 语义,查询 `(y1, y2)` 内部是否有 `x ≥ x1` 的点
面积计算 使用 `long long` 避免 `int` 乘法溢出

复杂度

- 时间:O(n \log n)(排序 + 每次线段树操作)
- 空间:O(n)(点数组、离散化数组、线段树)

http://www.gsyq.cn/news/1592898.html

相关文章:

  • 接入 LangFuse 实现全链路可观测:Token 消耗追踪、调用链分析与成本核算
  • OpenClaw 本地 AI 数字员工搭建教程 【安装全步骤 + 排错合集】
  • 嵌入式系统DMA技术解析:从CPU负载优化到eDMA与DMA_MUX实战应用
  • MPC866ADS内存控制器配置详解:从寄存器编程到嵌入式系统稳定运行
  • 【NSX入门黄金2小时】:仅需2台ESXi+1台NSX Manager,手把手搭建可验证的微隔离实验环境
  • eDMA错误处理机制详解:从寄存器配置到健壮驱动框架构建
  • 局部共形平坦流形上的修正度量构造与Weyl能量计算
  • 【ESXi 7.0零基础部署黄金手册】:20年VMware架构师亲授,避开97%新手踩坑的5大致命错误
  • Elsevier-Tracker:高效科研工作者的智能审稿监控解决方案
  • USB 2.0主机控制器核心机制:Ping协议与拆分事务深度解析
  • 嵌入式Flash控制器性能优化:从AHB总线访问到PFLASH2P实战配置
  • MPC8308 SerDes与eTSEC寄存器深度解析:从硬件原理到嵌入式网络驱动实战
  • Golang安全工具集构建指南:从信息收集到后渗透的63个实战工具
  • DownKyi完整使用指南:B站视频下载的终极解决方案
  • 3个技巧让你的macOS菜单栏瞬间变整洁:Ice终极管理指南
  • MPC8379E eTSEC中断机制深度解析:从寄存器到驱动实战
  • 具身机器人芯片测试
  • 嵌入式安全基石:PBRIDGE外设桥接原理与实战配置指南
  • 终极指南:如何用Roblox FPS解锁器打破60帧限制
  • 算法(单调队列、优先队列)
  • 5分钟掌握8球台球辅助工具:提升瞄准精度的终极指南
  • MCP1631 PWM控制器:智能电源与电池充电系统设计实战
  • SAP RFC Adapter 调试属性深解,从 Payload 切片到 Server Listener Trace 的排障思路
  • LLM聊天机器人质量评估实战指南:从幻觉检测到多轮状态追踪
  • Copier 总报错?一篇讲透排查、升级、治理和团队落地
  • 2026年私人音乐厅打造,揭秘全球**声学品牌声场技术天差地别
  • 网络处理器内核服务:事件定时器、上下文管理与同步机制深度解析
  • MC9S12HY PIM模块实战:引脚复用、寄存器配置与调试指南
  • 如何快速掌握Android虚拟定位:无需Root的终极解决方案
  • MC9S12HY/HA系列ADC12B8C模块配置与实战指南