• 53.最大子数组和


    【题目描述】

    给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

    子数组 是数组中的一个连续部分。

    输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
    输出:6
    解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
    输入:nums = [5,4,-1,7,8]
    输出:23
     【贪心思路】

    这个题目一开始想到的是贪心,因为从第一个数字开始,用sum记录当前的数组和是多少,用maxt记录sum数组和是否是最大的,满足则将maxt赋值为sum。其中要注意的是sum和maxt的初始值是0,但是如果遇到数组全部为负数的情况,就会出错,此时要加上一个特判。

    【贪心代码】
    1. class Solution {
    2. public:
    3. int maxSubArray(vector<int>& nums) {
    4. int maxt=0;
    5. int sum=0;
    6. int flag=0;
    7. int x=-100000;
    8. for(int i=0;i<nums.size();i++){
    9. if(nums[i]>=0){
    10. flag=1;
    11. }
    12. if(nums[i]>x){
    13. x=nums[i];
    14. }
    15. sum=nums[i]+sum;
    16. if(sum<0){
    17. sum=0;
    18. }
    19. if(sum>maxt){
    20. maxt=sum;
    21. }
    22. }
    23. if(flag==0){
    24. maxt=x;
    25. }
    26. return maxt;
    27. }
    28. };
    【分治法思路】

    分治法是将一个问题划分为同类型的若干个子问题,然后对子问题求解。

    当子问题足够大时,需要递归求解时,我们称之为递归情况(Recursive Case)。当子问题变得足够小,不再需要递归时,表示递归已经“触底”,进入了基本情况(Base Case)

    分治法的时间复杂度是O(nlog(n)),空间复杂度是O(long(n))

    这个题运用分治法:取数组中心点为中心,最大子序要么在中心左边要么在中心右边,要么跨中心。在中心左边或右边时,可以直接采用递归,跨中心的情况,再分治成中心点左侧和右侧的最大子序和的问题,这个是用贪心解决。

    【分治法代码】
    1. class Solution {
    2. public:
    3. int maxSubArray(vector<int>& nums) {
    4. int result=0;
    5. result=maxFun(nums,0,nums.size()-1);
    6. return result;
    7. }
    8. int maxFun(vector<int>& nums,int left,int right){
    9. //该数组只有一个数的情况
    10. if(right==left){
    11. return nums[left];
    12. }
    13. int mid=(left+right)/2;
    14. int rightSum=maxFun(nums,mid+1,right);
    15. int leftSum=maxFun(nums,left,mid);
    16. int midSum=midFun(nums,left,mid,right);
    17. int result=max(rightSum,leftSum);
    18. result=max(result,midSum);
    19. return result;
    20. }
    21. int midFun(vector<int>& nums,int left,int mid,int right){
    22. int leftSum=INT_MIN;
    23. int rightSum=INT_MIN;
    24. int sum=0;
    25. for(int i=mid;i>=left;i--){
    26. sum=sum+nums[i];
    27. if(sum>leftSum){
    28. leftSum=sum;
    29. }
    30. }
    31. sum=0;
    32. for(int i=mid+1;i<=right;i++){
    33. sum=sum+nums[i];
    34. if(rightSum<sum){
    35. rightSum=sum;
    36. }
    37. }
    38. return leftSum+rightSum;
    39. }
    40. };

  • 相关阅读:
    React动态生成二维码和毫米(mm)单位转像素(px)单位
    如何快速检测是否为空白字符
    Python数据分析实战-实现T检验(附源码和实现效果)
    java计算机毕业设计在线购物系统源程序+mysql+系统+lw文档+远程调试
    FFmpeg 常用API
    问道管理:机器人产业迎催化 黄金价格或将突破前高
    ASP.NET Core 6框架揭秘实例演示[30]:利用路由开发REST API
    AUTOSAR知识点 之NvM(二):FEE分析
    算法提升(一)二分法
    Java通过HttpURLConnection访问页面并解析HTML文件元素
  • 原文地址:https://blog.csdn.net/m0_73172034/article/details/134499641