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

Qwen模型 LeetCode 2577. 在网格图中访问一个格子的最少时间 C语言实现

哇!你也是C语言爱好者吗?我超爱用C写算法的,虽然要手动管理内存有点麻烦,但运行效率真的香啊!

让我给你写个清爽的C语言版本。这道题的关键是要实现一个最小堆(优先队列),咱们来撸个完整的解决方案:

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

// 定义方向数组:上、下、左、右
int dirs[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};

// 定义节点结构
typedef struct {
int time;
int x;
int y;
} Node;

// 最小堆结构
typedef struct {
Node* data;
int size;
int capacity;
} MinHeap;

// 创建堆
MinHeap* createHeap(int capacity) {
MinHeap* heap = (MinHeap*)malloc(sizeof(MinHeap));
heap->data = (Node*)malloc(sizeof(Node) * capacity);
heap->size = 0;
heap->capacity = capacity;
return heap;
}

// 交换节点
void swap(Node* a, Node* b) {
Node temp = *a;
*a = *b;
*b = temp;
}

// 上浮调整
void pushUp(MinHeap* heap, int index) {
while (index > 0) {
int parent = (index - 1) / 2;
if (heap->data[parent].time <= heap->data[index].time) break;
swap(&heap->data[parent], &heap->data[index]);
index = parent;
}
}

// 下沉调整
void pushDown(MinHeap* heap, int index) {
int smallest = index;
int left = 2 * index + 1;
int right = 2 * index + 2;

if (left < heap->size && heap->data[left].time < heap->data[smallest].time) {
smallest = left;
}
if (right < heap->size && heap->data[right].time < heap->data[smallest].time) {
smallest = right;
}

if (smallest != index) {
swap(&heap->data[index], &heap->data[smallest]);
pushDown(heap, smallest);
}
}

// 插入元素
void push(MinHeap* heap, int time, int x, int y) {
if (heap->size >= heap->capacity) return;

heap->data[heap->size].time = time;
heap->data[heap->size].x = x;
heap->data[heap->size].y = y;
pushUp(heap, heap->size);
heap->size++;
}

// 弹出最小元素
Node pop(MinHeap* heap) {
Node result = heap->data[0];
heap->size--;
heap->data[0] = heap->data[heap->size];
pushDown(heap, 0);
return result;
}

// 判断堆是否为空
int isEmpty(MinHeap* heap) {
return heap->size == 0;
}

int minimumTime(int** grid, int gridSize, int* gridColSize){
int m = gridSize;
int n = gridColSize[0];

// 特判:如果起点周围的格子都打不开
if (grid[0][1] > 1 && grid[1][0] > 1) {
return -1;
}

// 距离数组,记录到达每个位置的最短时间
int** dist = (int**)malloc(m * sizeof(int*));
for (int i = 0; i < m; i++) {
dist[i] = (int*)malloc(n * sizeof(int));
for (int j = 0; j < n; j++) {
dist[i][j] = INT_MAX;
}
}

// 创建堆,容量设大一点
MinHeap* heap = createHeap(m * n * 4);
push(heap, 0, 0, 0);
dist[0][0] = 0;

while (!isEmpty(heap)) {
Node curr = pop(heap);
int time = curr.time;
int x = curr.x;
int y = curr.y;

// 到达终点
if (x == m - 1 && y == n - 1) {
// 释放内存
for (int i = 0; i < m; i++) free(dist[i]);
free(dist);
free(heap->data);
free(heap);
return time;
}

// 如果当前时间已经大于记录的最短时间,跳过
if (time > dist[x][y]) continue;

// 探索四个方向
for (int i = 0; i < 4; i++) {
int nx = x + dirs[i][0];
int ny = y + dirs[i][1];

// 边界检查
if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;

// 计算到达邻居格子需要的时间
int nextTime;
if (time + 1 >= grid[nx][ny]) {
nextTime = time + 1;
} else {
// 需要等待,考虑奇偶性
int wait = grid[nx][ny] - time;
nextTime = grid[nx][ny] + (wait % 2 == 0 ? 1 : 0);
}

// 松弛操作
if (nextTime < dist[nx][ny]) {
dist[nx][ny] = nextTime;
push(heap, nextTime, nx, ny);
}
}
}

// 释放内存
for (int i = 0; i < m; i++) free(dist[i]);
free(dist);
free(heap->data);
free(heap);

return -1;
}
```

嘿,写完这个代码我都有点小骄傲呢!C语言虽然要手动处理内存,但这种掌控感真的很棒对吧?

有几个小细节特别有意思:
1. 堆的容量要设足够大,我一般会预估为 `m*n*4`
2. 内存泄漏是大忌,一定要记得在返回前释放所有动态分配的内存
3. 那个奇偶性判断特别巧妙,就像是在玩节奏游戏要踩准拍子

你平时喜欢用C写算法题吗?我觉得用C写题就像在玩极限挑战,既要考虑算法正确性,还要注意内存安全,特别锻炼基本功!要不要再来一道类似的题目练练手?😄

http://www.jsqmd.com/news/874761/

相关文章:

  • CSS Web安全字体
  • Godot 4地形性能修复:图层混合、LOD切换与法线生成三大断点解决方案
  • 前端国际化:复数规则与文案匹配深度解析
  • 别再死记硬背Sobel算子公式了!用Python+OpenCV手把手带你拆解卷积核的底层逻辑
  • 国内304不锈钢橱柜加工厂专业能力排行盘点:不锈钢钣金加工厂/专业不锈钢橱柜厂家/全屋定制不锈钢橱柜/定做不锈钢橱柜厂家/选择指南 - 优质品牌商家
  • Calico BGP故障诊断:从BIRD未就绪到Established的全链路排查
  • 前端国际化框架对比:i18next vs react-i18next vs Lingui vs Format.js
  • CVE-2024-38819漏洞复现:Tomcat 10.1.22 JNDI注入完整验证指南
  • 嵌入式开发中的字节序解析与C51实现方案
  • 从LightGBM到逻辑回归:手把手教你用category_encoders库搞定5种特征编码
  • AI同质化与认知依赖:金融系统性风险的新挑战与监管应对
  • 十年未更新的开源激光计算器LaserCalc,在2024年还能怎么用?我的实战踩坑与配置指南
  • Windows计划任务schtasks命令的‘隐藏’玩法与避坑指南:从权限设置到中文路径处理
  • 量子Jacobi-Davidson方法:电子结构计算的高效算法
  • 前端国际化:数字与货币格式化实战指南
  • 别再手动改路由了!用NetworkManager在麒麟KOS里永久固定双网卡优先级
  • 量子计算在蛋白质折叠问题中的应用与BF-DCQO算法解析
  • 保姆级教程:用ESM-2模型为你的蛋白质序列生成向量表示(Python实战)
  • 2026成都自动化测试公司推荐榜:成都自动化测试、成都车载测试、成都软件测试、成都金融测试、成都鸿蒙测试、成都IT培训公司选择指南 - 优质品牌商家
  • 8051开发中PDATA内存优化使用指南
  • ISP模型与硬件平台配置迁移实践指南
  • 前端国际化:语言检测与切换策略完全指南
  • DL:生成对抗网络的基本原理与 PyTorch 实现
  • 【Python趣味编程】用 Tkinter 打造“爱心便签墙”:一份来自代码的温柔
  • MacBook Pro M2开机密码忘了别慌!实测通过恢复模式+Apple ID重置全流程(附终端备用方案)
  • 四川网站建设公司推荐榜:成都CRM开发、成都GEO优化、成都UI设计、成都小程序开发、成都系统开发、成都网站开发选择指南 - 优质品牌商家
  • 解决ST-Link USB通信错误的全面指南
  • 2026Q2成都鑫达嘉丰保温技术服务对接实操全指南:成都鑫达嘉丰保温材料有限公司联系/防水基层板厂家/防水背衬板批发/选择指南 - 优质品牌商家
  • 告别龟速下载!保姆级教程:用迅雷+清华镜像源搞定Debian12完整版ISO
  • ARMv8-M异常优先级机制与安全扩展详解