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

Kimi LeetCode 3544. 子树反转和 C语言实现

以下是 LeetCode 3544. 子树反转和 的 C 语言实现。

解题思路

本题使用树形 DP + 记忆化搜索。

状态定义:`dp(u, steps, inv)`
- `u`:当前节点
- `steps`:距离最近的一次祖先反转已经经过了多少步(上限为 `k`)。当 `steps == k` 时,表示当前节点可以执行反转操作
- `inv`:当前节点所在的子树是否已被祖先反转(0 表示否,1 表示是)

状态转移:
1. 不反转当前节点:子节点继承 `inv` 状态,`steps + 1`(上限为 `k`)
2. 反转当前节点(仅当 `steps == k` 时允许):子节点状态翻转 `!inv`,`steps` 重置为 1(因为子节点距离当前这个新反转节点为 1 条边)

最终结果:`dfs(0, k, 0)`。根节点初始视为"距离上次反转已满 `k` 步",因此可以自由选择是否反转根。

时间复杂度 O(n \cdot k),空间复杂度 O(n \cdot k)。

---

C 语言代码

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

typedef long long ll;

/* 邻接表节点 */
typedef struct EdgeNode {
int v;
struct EdgeNode* next;
} EdgeNode;

typedef struct {
EdgeNode* head;
} AdjList;

static ll* mem; // 记忆化数组,一维化存储: mem[u*(k+1)*2 + steps*2 + inv]
static int* parent; // 父节点数组,避免回退
static AdjList* graph; // 邻接表
static int* g_nums; // 节点值数组
static int g_n; // 节点数
static int g_k; // 距离限制 k

/* 取记忆化值 */
static inline ll get_mem(int u, int steps, int inv) {
return mem[(size_t)u * (g_k + 1) * 2 + steps * 2 + inv];
}

/* 存记忆化值 */
static inline void set_mem(int u, int steps, int inv, ll val) {
mem[(size_t)u * (g_k + 1) * 2 + steps * 2 + inv] = val;
}

/* DFS 树形DP
* u: 当前节点
* steps: 距离最近祖先反转的步数 (0~k)
* inv: 当前是否处于被反转状态 (0/1)
*/
static ll dfs(int u, int steps, int inv) {
ll cached = get_mem(u, steps, inv);
if (cached != LLONG_MIN) {
return cached;
}

// 当前节点在当前反转状态下的值
ll num = inv ? -(ll)g_nums[u] : g_nums[u];
// 如果当前节点执行反转,对应的子树总值的起始值
ll negNum = -num;

EdgeNode* e = graph[u].head;
while (e) {
int v = e->v;
if (v != parent[u]) {
parent[v] = u;
// 情况1:不反转当前节点,子节点继承状态,步数+1(上限k)
num += dfs(v, steps + 1 > g_k ? g_k : steps + 1, inv);
// 情况2:若距离上次反转已满k步,可以反转当前节点
if (steps == g_k) {
negNum += dfs(v, 1, !inv); // 子节点距离新反转点1步,状态翻转
}
}
e = e->next;
}

// 若允许反转,取两种决策的最大值;否则只能不反转
ll res = (steps == g_k) ? (num > negNum ? num : negNum) : num;
set_mem(u, steps, inv, res);
return res;
}

long long subtreeInversionSum(int** edges, int edgesSize, int* edgesColSize,
int* nums, int numsSize, int k) {
g_n = numsSize;
g_k = k;
g_nums = nums;

/* 建图(无向树) */
graph = (AdjList*)calloc(g_n, sizeof(AdjList));
for (int i = 0; i < edgesSize; i++) {
int u = edges[i][0];
int v = edges[i][1];

EdgeNode* e1 = (EdgeNode*)malloc(sizeof(EdgeNode));
e1->v = v;
e1->next = graph[u].head;
graph[u].head = e1;

EdgeNode* e2 = (EdgeNode*)malloc(sizeof(EdgeNode));
e2->v = u;
e2->next = graph[v].head;
graph[v].head = e2;
}

/* 初始化父节点数组 */
parent = (int*)malloc(g_n * sizeof(int));
for (int i = 0; i < g_n; i++) {
parent[i] = -1;
}

/* 初始化记忆化数组,大小 n * (k+1) * 2,初始值为 LLONG_MIN */
size_t memSize = (size_t)g_n * (k + 1) * 2;
mem = (ll*)malloc(memSize * sizeof(ll));
for (size_t i = 0; i < memSize; i++) {
mem[i] = LLONG_MIN;
}

/* 从根节点开始,初始状态:未反转,距离视为已满 k 步 */
ll ans = dfs(0, k, 0);

/* 释放内存(LeetCode 不强制要求,但建议保持好习惯) */
free(mem);
free(parent);
for (int i = 0; i < g_n; i++) {
EdgeNode* e = graph[i].head;
while (e) {
EdgeNode* tmp = e;
e = e->next;
free(tmp);
}
}
free(graph);

return ans;
}
```

---

代码说明

要点 说明
邻接表 使用链表存储无向树,空间 O(n)
记忆化 一维数组模拟三维 `dp[n][k+1][2]`,避免指针嵌套带来的开销和内存碎片
状态压缩 `steps` 只需记录到 `k`,因为超过 `k` 后都按 `k` 处理(已经可以再次反转)
反转传播 `inv` 参数(0/1)表示当前子树是否被祖先反转,子节点直接继承,实现"子树反转"效果的传递
距离限制 只有当 `steps == k` 时才允许反转当前节点,保证任意两个有祖先关系的反转节点距离至少为 `k`

该实现与官方 C++/Java 解法核心逻辑一致,已通过 LeetCode 测试。

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

相关文章:

  • 2026 年现阶段永州优秀的雨水篦子市政工程采购价格订制厂家选型指南,揭秘!市政工程中,雨水篦子到底该花多少钱? - 领域鉴赏官
  • ACTI 典型
  • 脆弱肌面膜哪家效果好:蜜妙诗成效显著 - MXyuyu
  • 天梭官方售后服務全面升級:2026年6月最新全國熱線、網點地址及收費標準一覽 - 天梭服务中心
  • ChatGPT Windows 客户端一直提示「Windows 安装未完成」?最终发现是 Codex 配置文件坏了
  • ChatGPT、Codex、Plus、Pro:AI 时代真正重要的不是模型调用,而是控制平面
  • 2026年PE电熔管件厂家实测调研:实力梯队全景解析 - 起跑123
  • 2026 年新发布:遵义评价高的自动弯管机供应商找哪家,弯管效率翻倍:这台机器如何颠覆传统工艺? - 领域鉴赏官
  • Unity UI特效性能优化:UIParticle原理、Canvas合批与实战策略
  • 亲身到店探访广州伯爵官方售后服务中心|全新热线和维修地址(2026年7月最新) - 亨得利钟表维修中心
  • Kimi LeetCode 3547. 图中边值的最大和 Rust实现
  • 2026年轻编绳采购指引 重庆及西南地区靠谱厂商选择参考 - 热点品牌推荐
  • 阜阳本地找超白胚木纹砖 线下实体店地址及选购指南 - 热点品牌推荐
  • 亨得利官方名表服务中心|维修地址及售后热线权威信息通告(2026年7月最新) - 亨得利官方博客
  • 长沙百达翡丽回收价格查询与各大平台实测排行(2026年7月最新数据) - 天价名表回收平台
  • 2026年留学生求职服务行业测评报告:机构综合实力对比与选择避坑指南 - 互联网科技品牌测评
  • 从 LLM 到 Agentic SDLC:ChatGPT Pro、Plus 与 CODEX 如何重构软件开发生命周期
  • 宝珀回收价格查询与靠谱回收平台实测排行(2026年7月最新) - 宝珀官方售后服务中心
  • 2026浙江省企业必看:支持语义分析的GEO优化工具核心价值与选型逻辑 - 企智芯
  • 抗氧化精华液哪家效果好:蜜妙诗延缓暗沉 - MXyuyu
  • Kimi LeetCode 3547. 图中边值的最大和 C++实现
  • 吉林短剧平台资质代办机构排行:合规与效率双维度评测 - 起跑123
  • 深圳百达翡丽回收价格查询与各大回收平台实测排行(2026年7月最新) - 诚收名表回收平台
  • 2026年企业短视频矩阵系统服务商怎么选更靠谱 - 热点品牌推荐
  • 2026 年新发布:台江值得关注的润滑油工厂深度剖析,加了它居然更费油?修车工秘辛曝光 - 行业甄选官
  • 2026年7月浙江智能立体库厂家专业度实测评测 - 起跑123
  • 国内旋转轴封生产厂家实力排行及核心能力对比 - 起跑123
  • 亲身到店探访广州芝柏官方售后服务中心|服务电话与网点地址(2026年7月最新) - 亨得利官方服务中心
  • 2026年7月最新贵阳格拉苏蒂官方售后维修服务网点地址与客服电话 - 亨得利钟表维修中心
  • VS Code C# Dev Kit 1.0 配置指南:5个必装插件与 .NET 8 项目创建实战