树形动态规划:为什么一棵树的答案要从叶子开始算
给定一棵二叉树,找出其直径——这条路径可能穿过根节点,也可能完全在某个子树中。当你第一次看到 LeetCode 543 这道题时,可能会想:从根节点出发,找到最深的左节点和最深的右节点,把两条路径连起来不就是答案吗?但这个直觉会出错——直径可能根本不经过根节点。 ...
给定一棵二叉树,找出其直径——这条路径可能穿过根节点,也可能完全在某个子树中。当你第一次看到 LeetCode 543 这道题时,可能会想:从根节点出发,找到最深的左节点和最深的右节点,把两条路径连起来不就是答案吗?但这个直觉会出错——直径可能根本不经过根节点。 ...
假设你需要在一段百万字的文本中搜索一个关键词。最直观的方法是:将关键词与文本的每个位置逐一比较——时间复杂度 $O(nm)$,其中n是文本长度,m是关键词长度。当文本达到百万级别时,这个算法可能需要数秒甚至更长。 ...
假设你需要统计小于1000万的整数中有多少个素数。最直观的想法是:对每个数逐一判断是否为素数——时间复杂度 $O(n\sqrt{n})$,当数据量达到千万级别时,程序可能需要运行数秒甚至数分钟。但如果换一个思路:用一个布尔数组标记所有合数,剩下的就是素数——时间复杂度骤降至 $O(n \log \log n)$,千万级数据量下只需几十毫秒。 ...
假设你需要统计一个整数二进制表示中1的个数。最直观的想法是:转成二进制字符串,遍历统计每个字符——代码大概十行左右。但如果告诉你,用一行循环就能搞定,甚至不需要字符串转换呢? ...
1961年,英国计算机科学家Tony Hoare在为机器翻译项目开发字典排序功能时,发明了一种在当时看来极其反直觉的算法:随机选择一个元素作为基准,将数组分成两部分递归排序。这个算法就是后来统治计算机排序领域半个多世纪的快速排序。 ...
假设你需要为$n$个城市铺设光缆,每两个城市之间的铺设成本各不相同。如何用最低的总成本让所有城市互联互通?这看似是一个复杂的优化问题,实际上可以抽象为图论中的经典问题——最小生成树(Minimum Spanning Tree,简称MST)。 ...
1966年,计算机科学家们在设计操作系统时面临一个核心问题:当内存空间有限而需要存储的数据量无限增长时,应该删除哪些数据?这个看似简单的问题催生了缓存淘汰策略的研究。在众多策略中,LRU(Least Recently Used,最近最少使用)因其简单直观的思想和优秀的实际表现,成为应用最广泛的缓存淘汰算法之一。 ...