求最大字段和(穷举法、动态规划、分治法)

这篇具有很好参考价值的文章主要介绍了求最大字段和(穷举法、动态规划、分治法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


1、案例要求

给定由n个整数(可能为负整数)组成的序列a1,a2,…,an,求该序列形如:最大字段和的分治算法,算法笔记,动态规划,算法,数据结构
的子段和的最大值。当所有整数均为负数时定义其最大子段和为0。

分别采用穷举法、分治法、动态规划法完成。

2、算法设计与实现
2.1 穷举法
2.1.1 算法设计思路

通过定义遍历子段起始位置与子段和长度将所有情况计算一遍,从而得到最大子段和;

2.1.2 代码实现

时间复杂度:O(n2)

public static int qiuju(int[] nums){
    int len=nums.length;
    if(len==1) return nums[0];
    int res=nums[0];

    //起始位置
    for(int i=0;i<len;i++){
        //子段和长度
        int max=0;
        for(int j=1;j<=len-i;j++){
            max+=nums[i+j-1];
            res=Math.max(res,max);
        }
    }
    return res;
}
2.2 动态规划
2.2.1 算法设计思路

将问题转移为求以各数组元素结尾的子段最大和,对每个序列元素求结尾最大子段和时,通过比较前一个元素结尾最大子段和是否为负数,是则重新开始,否则拼接到上一个连续子段,最后比较所有的结尾最大子段和得到最大子段和。

2.2.2 实现代码

时间复杂度:O(n)

public static int dynamicProgram(int[] nums){
    int len=nums.length;
    if(len==1) return nums[0];
    //状态转移数组,以nums[i]结尾的连续子数组的最大和
    int[] dp=new int[len];
    dp[0]=nums[0];

    for(int i=1;i<len;i++){
        if(dp[i-1]<0){
            //前一个数组元素结尾的最大和为负,重新开始
            dp[i]=nums[i];
        }else{
            //拼接到上一个连续子数组
            dp[i]=dp[i-1]+nums[i];
        }
    }

    int res=nums[0];
    //遍历dp数组,找到最大和所在结尾nums元素,
    // 并返回最大和
    for(int num:dp){
        res=Math.max(res,num);
    }
    return res;
}
2.3 分治法
2.3.1 算法实现思路

将序列分为三部分进行求解,分别是[left,mid]、[mid,mid+1]、[mid+1,right],分别对三部分求最大子段和,最后比较三部分得到最大子段和。

2.3.2 代码实现

时间复杂度:O(nlog2n)

public static int fenzhi(int[] nums,int left,int right){
    //分到中间位置重合,结束递归
    if(left==right){
        return nums[left];
    }
    //确定中间位置
    int mid=left+(right-left)/2;
    //返回三种情况的最大值
    return Max3(fenzhi(nums,left,mid),
                fenzhi_mid(nums,left,mid,right),
                fenzhi(nums,mid+1,right));
}

public static int fenzhi_mid(int[] nums,int left,int mid,int right){
    int sum=0;
    //确定左边最大和
    int left_sum=Integer.MIN_VALUE;
    //从中间往左遍历,不能从左开始
    for(int i=mid;i>=left;i--){
        sum+=nums[i];
        left_sum=Math.max(sum,left_sum);
    }

    sum=0;
    //确定右边最大和
    int right_sum=Integer.MIN_VALUE;
    for(int i=mid+1;i<=right;i++){
        sum+=nums[i];
        right_sum=Math.max(right_sum,sum);
    }
    //返回左右之和
    return left_sum+right_sum;
}

public static int Max3(int n1,int n2,int n3){
    //返回三数之和最大值
    return Math.max(n1,Math.max(n2,n3));
}
3、总结

动态规划的算法思路与代码实现较难,其适用于解最优化问题,其求解三大步骤:定义数组dp[i]中元素含义、找出数组元素之间的关系式、找出初始值较为关键,需充分理解题意再开始进行代码实现!文章来源地址https://www.toymoban.com/news/detail-784194.html

到了这里,关于求最大字段和(穷举法、动态规划、分治法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【LeetCode: 53. 最大子数组和 | 暴力递归=>记忆化搜索=>动态规划 | 分治法 】

    🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文

    2023年04月21日
    浏览(58)
  • 3.4动态规划--最大字段和

    要好好学习这个难受难受超级难受的动态规划了,千万不要再沉迷在看剧和玩耍里面了。必须承认最近没有好好学习。 最大字段和书上介绍了三种解法:暴力、递归分治、动态规划 递归分治,一分为二,合并的时候有三种情况,注意考虑清楚 动态规划,最优解的数组b[j]表示

    2024年02月02日
    浏览(29)
  • 算法分析与设计---分治+动态规划

    1.分治法 适用条件: 问题规模缩小到一定程度容易求解 问题可以分解为若干个规模较小的 相同 子问题,即问题具有最优子结构( 使用分治法前提 ) 可以利用子问题的解合并为该问题的解( 决定是否使用分治法 ) 各个子问题 相互独立 ,即子问题之间不包含公共子问题(

    2024年02月07日
    浏览(32)
  • 四大算法:贪心、分治、回溯、动态规划

    贪心算法(又称贪婪算法),在求解问题时,总是做出在当前看来是最好的选择。也就是说,不从整体最优解进行考虑,而是得到某种意义上的局部最优解。 贪心算法采用自顶向下,以迭代的方法做出贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的问题。

    2024年02月15日
    浏览(29)
  • 最大字段和(动态规划,C语言)

    递推关系 对于数组A[]={1,2,3,-4,-3,2,1}, 如果有一个函数endsum(j),求出以位置j为终止点的最大子段和,则满足 if(endsum(j-1)0) endsum(j)=endsum(j-1)+A[j] else endsum(j)=A[j] 因为此时A[j]前面的元素只能降低和 上述递推关系是针对endsum 而最大子段和maxsum= max(endsum(0),endsum(1),...endsum(N-1)) 测

    2024年02月03日
    浏览(26)
  • 探索经典算法:贪心、分治、动态规划等

    贪心算法是一种常见的算法范式,通常在解决最优化问题中使用。 贪心算法是一种在每一步选择中都采取当前状态下最优决策的算法范式。其核心思想是选择每一步的最佳解决方案,以期望达到最终的全局最优解。这种算法特点在于只考虑局部最优解,而不会回溯或重新考虑

    2024年02月05日
    浏览(30)
  • 五大常用算法——分治法,动态规划,回溯法,分支界限法,贪心算法

    (1) 分治法 将一个难以直接解决的大问题,分割成一些规模较小的相同问题 快速排序 快排也是分治的一个实例,快排每一趟会选定一个数,将比这个数小的放左面,比这个数大的放右面, 然后递归分治求解两个子区间,当然快排因为在分的时候就做了很多工作, 当全部分到

    2024年02月04日
    浏览(29)
  • (软考-软件设计师.下午)动态规划算法、回溯算法、贪心算法、分治算法的应用

    :【递归技术】【二分查找】 分治法的设计思路: 将一个难以直接解决的 大问题 分解成一些 规模较小 的相同问题以便于 逐个击破,分而治之 。      由代码可以看出二分查找也属于分治法的一种,关于二分查找,这位博主总结的很详细。  :【查表】   动

    2024年02月06日
    浏览(35)
  • 【leetcode刷题之路】剑指Offer(4)——分治+排序算法+动态规划

    8 分治算法 8.1 【递归】剑指 Offer 07 - 重建二叉树 https://leetcode.cn/problems/zhong-jian-er-cha-shu-lcof/   前序遍历是根左右,中序遍历是左根右,这也就意味着前序遍历的第一个节点是整棵树的根节点,顺着这个节点找到它在中序遍历中的位置,即为in_root,那么in_root左边的都在左子

    2024年02月11日
    浏览(43)
  • 算法思想—枚举、递推、迭代、递归、分治、贪心、动态规划、回溯、模拟、分支定界

    算法思想 枚举(暴力算法) 枚举算法(暴力算法)是一种通过逐一尝试所有可能解来解决问题的算法。它的基本思想是将问题的所有可能答案一一列举出来,并根据一定的判断条件来确定哪些答案是合适的。这种算法通常使用循环来实现,因为需要尝试所有可能的情况。两

    2024年02月01日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包