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

千问 LeetCode 2920. 收集所有金币可获得的最大积分 C语言实现

这道题的 C 语言解法,核心思路与 Java 版本完全一致,都是采用树形动态规划(Tree DP)结合记忆化搜索。由于 C 语言没有现成的集合与动态数组库,我们需要手动使用邻接表来建树,并自行管理内存。

以下是完整的 C 语言实现:

💻 C 语言代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义邻接表节点
typedef struct Node {
int val;
struct Node* next;
} Node;

// 创建新的邻接表节点
Node* createNode(int val) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->val = val;
newNode->next = NULL;
return newNode;
}

// 深度优先搜索(记忆化递归)
int dfs(int i, int j, int father, int** memo, Node** graph, int* coins, int k) {
// 如果该状态已经计算过,直接返回
if (memo[i][j] != -1) {
return memo[i][j];
}

// 当前节点 i 在经过 j 次减半后的实际金币数
int currentCoin = coins[i] >> j;

// 策略1:使用方式1收集 (coins[i] >> j) - k
int res1 = currentCoin - k;

// 策略2:使用方式2收集 (coins[i] >> j) / 2
int res2 = currentCoin >> 1;

// 遍历所有子节点(排除父节点)
Node* cur = graph[i];
while (cur != NULL) {
int child = cur->val;
if (child != father) {
// 累加策略1下,子树的收益
res1 += dfs(child, j, i, memo, graph, coins, k);

// 累加策略2下,子树的收益
// 剪枝:如果 j >= 13,说明再右移一次金币肯定为0,没必要继续深入递归计算 res2
if (j < 13) {
res2 += dfs(child, j + 1, i, memo, graph, coins, k);
}
}
cur = cur->next;
}

// 记录并返回最大值
memo[i][j] = (res1 > res2) ? res1 : res2;
return memo[i][j];
}

int maximumPoints(int** edges, int edgesSize, int* edgesColSize, int* coins, int coinsSize, int k) {
int n = coinsSize;

// 1. 构建邻接表表示树
Node** graph = (Node**)malloc(n * sizeof(Node*));
for (int i = 0; i < n; i++) {
graph[i] = NULL;
}

for (int i = 0; i < edgesSize; i++) {
int x = edges[i][0];
int y = edges[i][1];
// 无向图,双向添加边
Node* nodeY = createNode(y);
nodeY->next = graph[x];
graph[x] = nodeY;

Node* nodeX = createNode(x);
nodeX->next = graph[y];
graph[y] = nodeX;
}

// 2. 初始化记忆化数组 memo[i][j]
int** memo = (int**)malloc(n * sizeof(int*));
for (int i = 0; i < n; i++) {
memo[i] = (int*)malloc(14 * sizeof(int)); // j 最大取 14 即可
for (int j = 0; j < 14; j++) {
memo[i][j] = -1; // -1 表示未计算过
}
}

// 3. 从根节点 0 开始 DFS,初始父节点为 -1,初始减半次数为 0
int result = dfs(0, 0, -1, memo, graph, coins, k);

// 4. 释放内存
// 释放邻接表
for (int i = 0; i < n; i++) {
Node* cur = graph[i];
while (cur != NULL) {
Node* temp = cur;
cur = cur->next;
free(temp);
}
}
free(graph);

// 释放记忆化数组
for (int i = 0; i < n; i++) {
free(memo[i]);
}
free(memo);

return result;
}

📊 复杂度分析
* 时间复杂度:O(N)。虽然引入了状态 j,但因为金币最多减半 14 次就会变成 0,状态总数被限制在 N times 14 以内,每个状态只计算一次。
* 空间复杂度:O(N)。用于存储邻接表、记忆化数组以及递归调用的系统栈空间。

⚠️ C 语言实现注意事项
1. 手动建树:C 语言中没有 ArrayList,我们使用了结构体 Node 配合指针来构建邻接表(链式前向星或单链表均可)。
2. 内存管理:在 C 语言中,使用 malloc 分配的二维数组和链表节点,在函数返回前必须手动 free 释放,否则会导致内存泄漏。
3. 位运算:>> 右移运算在 C 语言中对于非负整数等同于除以 2 的幂,且效率更高。
4. 边界剪枝:依然保留了 if (j < 13) 的剪枝逻辑,防止无意义的递归调用。

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

相关文章:

  • 如何快速美化foobar2000:终极界面优化完整指南
  • 别再只会用Burp抓包了:手把手教你用APIKit和Param Miner插件高效发现API端点
  • 人机协作AI:从自动化到增强化的技术演进与应用实践
  • 别再搞混了!CAPL诊断脚本里DiagSetParameterRaw和DiagSetPrimitiveByte到底怎么选?
  • Halcon实战:巧用vector_field_length与local_max_sub_pix提升卫星云图粒子运动分析精度
  • 2026年评价高的江西同浴型固色剂/无醛固色剂/无酚固色剂/直接染料固色剂优质厂家推荐榜 - 品牌宣传支持者
  • 告别摄像头局限:手把手教你用激光雷达和ReID3D搭建更可靠的行人识别系统
  • 千问 LeetCode 2926. 平衡子序列的最大和 Java实现
  • 麒麟V10服务器上,毕昇JDK 1.8缺失javafx.util.Pair的快速修复指南
  • SAP后台配置保姆级指南:从SPRO入口到生产环境传请求,新手避坑全流程
  • 如何永久保存微信聊天记录:3步掌握WeChatMsg数据备份终极指南
  • 2026年评价高的给排水涂塑钢管/内外涂塑钢管优质供应商推荐 - 行业平台推荐
  • 如何用微信聊天记录打造你的专属AI记忆库:留痕项目完全指南
  • cyrillic_PP-OCRv5_mobile_rec_safetensors完全解析:从模型架构到实战应用
  • Lance图像理解能力实测:视觉问答与推理任务最佳实践指南
  • STM32F103C8T6用HAL库驱动74HC595,点亮三位数码管(附Proteus仿真文件)
  • OrCAD原理图端口用对了吗?从Place Port到Off-Page Connector,一篇讲清区别、选用与高效转换技巧
  • 2026武汉配眼镜推荐,进出空调房镜片一片雾,五家店防雾方案实测 - 配眼镜新资讯
  • 高效研究周报系统:从知识管理到团队协同的工程实践
  • 深度解析Listen1音乐扩展:从性能瓶颈到极致优化的实战指南
  • 虎链科技:以硬核实力驱动数字化创新,用年轻活力赋能企业未来
  • 2026年靠谱的同城旧中央空调回收/西安商用中央空调回收/空调回收高口碑品牌推荐 - 行业平台推荐
  • 洛雪音乐助手:5大优势让你告别音乐应用切换烦恼的终极指南
  • Phi-3.5-mini-instruct_Uncensored-GGUF快速入门:10分钟在LM Studio中运行你的第一个AI助手
  • 2026年评价高的西安空调回收免费上门估价/西安酒店空调回收拆除/家用旧空调回收/西安商用中央空调回收品质保障公司 - 品牌宣传支持者
  • 终极ZMK键盘固件教程:5个步骤打造你的完美无线工作台
  • STM32F103 RS485双模Modbus通信例程:按键切主从、LED实时反馈、含完整Keil工程
  • 告别打包失败:UE5 Android打包流程优化与自动化脚本分享(基于Android Studio 2023)
  • 30分钟终极指南:用OpCore-Simplify快速完成OpenCore EFI自动化配置
  • 别再浪费服务器资源了!用HBase 2.5.6自带Zookeeper,在CentOS 7上快速搭建伪分布式测试环境