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

算法高频题-动态规划

  • 刷题LeetCode(Top 100-150题,至少刷两遍)。重点:链表、树、二分查找、动态规划、回溯、栈/队列。

  • 每一个题型,前10个高频题

算法思考框架参考:算法题思维框架-CSDN博客

高频顺序参考网站:CodeTop 面试题目总结

1.53. 最大子数组和

这道题是动态规划的经典问题,主要有三种方法:

  1. Kadane算法(动态规划):最优解,O(n)时间复杂度

  2. 分治法:O(n log n)时间复杂度

  3. 暴力法:O(n²)时间复杂度(不推荐)

方法一:Kadane算法(动态规划)

class Solution {
public:int maxSubArray(vector<int>& nums) {if (nums.empty()) return 0;int maxSum = nums[0];    // 全局最大和int currentSum = nums[0]; // 当前子数组和for (int i = 1; i < nums.size(); i++) {// 对于每个元素,选择:要么加入当前子数组,要么重新开始currentSum = max(nums[i], currentSum + nums[i]);// 更新全局最大和maxSum = max(maxSum, currentSum);}return maxSum;}
};

方法二:分治法

class Solution {
public:int maxSubArray(vector<int>& nums) {return divideAndConquer(nums, 0, nums.size() - 1);}private:int divideAndConquer(vector<int>& nums, int left, int right) {if (left == right) return nums[left];int mid = left + (right - left) / 2;// 分别求左右两边的最大子数组和int leftMax = divideAndConquer(nums, left, mid);int rightMax = divideAndConquer(nums, mid + 1, right);// 求跨越中点的最大子数组和int crossMax = maxCrossingSum(nums, left, mid, right);return max({leftMax, rightMax, crossMax});}int maxCrossingSum(vector<int>& nums, int left, int mid, int right) {// 从中点向左的最大和int leftSum = INT_MIN;int sum = 0;for (int i = mid; i >= left; i--) {sum += nums[i];leftSum = max(leftSum, sum);}// 从中点向右的最大和int rightSum = INT_MIN;sum = 0;for (int i = mid + 1; i <= right; i++) {sum += nums[i];rightSum = max(rightSum, sum);}return leftSum + rightSum;}
};

方法三:动态规划(显式DP数组)

class Solution {
public:int maxSubArray(vector<int>& nums) {if (nums.empty()) return 0;int n = nums.size();vector<int> dp(n); // dp[i]表示以nums[i]结尾的最大子数组和dp[0] = nums[0];int maxSum = dp[0];for (int i = 1; i < n; i++) {dp[i] = max(nums[i], dp[i - 1] + nums[i]);maxSum = max(maxSum, dp[i]);}return maxSum;}
};
  • 时间复杂度

    • Kadane算法:O(n)

    • 分治法:O(n log n)

    • 暴力法:O(n²)

  • 空间复杂度

    • Kadane算法:O(1)

    • 分治法:O(log n)(递归栈)

    • 显式DP:O(n)

  1. "为什么Kadane算法有效?"

    • 基于贪心思想:如果当前子数组和为负数,它对后续子数组没有贡献

    • 可以重新开始计算子数组和

  2. "如何修改算法来返回最大子数组的起止位置?"

    class Solution {
    public:vector<int> maxSubArrayWithIndices(vector<int>& nums) {if (nums.empty()) return {0, 0, 0};int maxSum = nums[0];int currentSum = nums[0];int start = 0, end = 0;int tempStart = 0;for (int i = 1; i < nums.size(); i++) {if (nums[i] > currentSum + nums[i]) {currentSum = nums[i];tempStart = i;} else {currentSum += nums[i];}if (currentSum > maxSum) {maxSum = currentSum;start = tempStart;end = i;}}return {maxSum, start, end};}
    };
  3. "如果要求子数组长度至少为k怎么办?"

    需要使用滑动窗口或前缀和等更复杂的方法

2.5. 最长回文子串

http://www.dtcms.com/a/392779.html

相关文章:

  • 第七篇:强类型枚举:enum class - 彻底解决传统枚举的缺陷
  • 汽车中的轻量化 AI 算法:驶向智能出行新未来
  • 《根治开放世界坐骑卡顿:从时钟同步到负载均衡的架构级解决方案》
  • 在线预览Office文件全攻略
  • Cordova打包Vue项目成APK——真机调试
  • DNS协议、ICMP协议、NAT技术
  • HTML5 基础与常用标签
  • 2023 CCPC Online vp补题-D
  • 阿勒泰羊区域公用品牌在京发布 多方合力打造“雪都牧歌·天选之羊”产业新生态
  • 【分布式技术】Redis 双集群主备部署方案” 的详细说明
  • (信号)频谱泄露和频谱混叠
  • 蓝桥杯2024年第15届B组试题D
  • 【软考中级 - 软件设计师 - 基础知识】数据结构之线性表
  • Tomcat工作机制与Servlet流程详解
  • Netty从0到1系列之Recycler对象池技术【1】
  • 开始 ComfyUI 的 AI 绘图之旅-SD3.5文生图和图生图(全网首发,官网都没有更新)(十五)
  • [数理逻辑] 决定性公理与勒贝格可测性 (III) 有限维情况
  • 浅谈 “混合检索”和“重排”
  • 计算机视觉与深度学习 | 基于Matlab的雾霾天气和夜间车牌识别系统关键技术与架构设计
  • 二、PyTorch张量学习教程:从小白到高手的实战之旅
  • 名字空间,异常与匿名函数
  • DCM项目wan 1.3b T2V模型comfyui改造流程尝试
  • python编写的第一个appium自动化测试脚本
  • 道客巴巴文库资料免费下载的方法(不需要第三方软件)
  • 【C++】STL详解(九)—priority_queue的使用与模拟实现
  • 【车载开发系列】了解FlashDriver
  • 轻量化 AI 算法:开启边缘智能新时代
  • sward入门到实战(3) - 如何管理文档
  • 贝叶斯优化(Bayesian Optimization)实战:超参数自动搜索的黑科技
  • CSP-S2025 第一轮试题(附答案)