美文网首页
算法-分治最大子序和问题

算法-分治最大子序和问题

作者: li_礼光 | 来源:发表于2021-01-06 11:48 被阅读0次

分治

分治法的基本思想:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

可以使用分治法求解的一些经典问题

  1. 二分搜索
  2. 大整数乘法
  3. Strassen矩阵乘法
  4. 棋盘覆盖
  5. 合并排序
  6. 快速排序
  7. 线性时间选择
  8. 最接近点对问题
  9. 循环赛日程表
  10. 汉诺塔

53. 最大子序和

package com.company;

public class fenzhi {

  public static void main(String[] args) {
//    int[] temp = {-1,-2,-5,-4,-5,-6,-7,-1};
    int[] temp = {8,-19,5,-4,20};
    System.out.println("最终结果 : " + maxSubArray(temp));
  }

  public static int maxSubArray(int[] nums) {
    return findSubsequence(0,nums.length - 1,nums);
  }

  // 计算resul数组
  // begin : 数组最开始的索引
  // end : 数组最后的索引
  // 最大正子序列和
  public static int findSubsequence(int begin , int end , int[] result) {
    if (begin < 0 || end < 0) return 0;
    // 数组就只有一个元素, 也就是begin = end,
    if (end - begin == 0) return result[begin];


    // 数组有2个及以上的元素

    // 求出中间值
    // 0, 1, 2, 3, 4, 5, 6,
    // 如果当前 begin = 0, end = 1; mid = 1     [0] [1]                   left (begin,begin + mid - 1)  right(begin + mid,end)
    // 如果当前 begin = 0, end = 2; mid = 1     [0] [1,2]                 left (begin,begin + mid - 1)  right(begin + mid,end)
    // 如果当前 begin = 0, end = 3; mid = 2     [0,1] [2,3]               left (begin,begin + mid - 1)  right(begin + mid,end)
    // 如果当前 begin = 0, end = 4; mid = 2     [0,1] [2,3,4]             left (begin,begin + mid - 1)  right(begin + mid,end)
    // 如果当前 begin = 0, end = 5; mid = 3     [0,1,2] [3,4,5]           left (begin,begin + mid - 1)  right(begin + mid,end)
    // 如果当前 begin = 0, end = 6; mid = 3     [0,1,2] [3,4,5,6]         left (begin,begin + mid - 1)  right(begin + mid,end)
    // 如果当前 begin = 0, end = 7; mid = 4     [0,1,2,3] [4,5,6,7]       left (begin,begin + mid - 1)  right(begin + mid,end)
    int mid = (end - begin + 1) >> 1 ;

    // ==============================================
    // 计算中间区间的最大值
    // 从中间往左相加 左边 [begin, mid)
    int leftMax = result[begin + mid - 1];
    int leftSum = 0;
    for (int i = begin + mid - 1; i >= begin ; i--) {
      leftSum = leftSum + result[I];
      if (leftSum > leftMax) {
        leftMax = leftSum ;
      }
    }

    // 从右边往左相加 右边 [mid, end]
    int rightMax =  result[begin + mid ];
    int rightSum = 0;
    for (int i = begin + mid ; i <= end ; i++) {
      rightSum = rightSum + result[I];
      if (rightSum > rightMax) {
        rightMax = rightSum ;
      }
    }
    int midMax = leftMax + rightMax;

    // ==============================================
    // 递归计算左边区间的最大值
    int leftEdgeMax = findSubsequence(begin, begin + mid - 1, result);

    // 递归计算右边区间的最大值
    int rightEdgeMax = findSubsequence(begin + mid , end, result);

    // 最终结果
    int res = rightEdgeMax > leftEdgeMax ? rightEdgeMax : leftEdgeMax;
    res = midMax > res ? midMax : res;
    return res;
  }
}

PS : 这里注意每一段的区间的begin, mid, end三者的对应关系

输出 :

最终结果 : 21

复杂度分析 :

两个for循环: 2 * O(n/2)
两个递归 : 2 * O(logn);

LeetCode结果:


LeetCode

思路 :
分为三部分, 左边部分, 右边部分, 中间向左和右延伸部分


思路

相关文章

  • 10《算法入门教程》分治算法之最大子数组问题

    1. 前言 本节内容是分治算法系列之一:最大子数组问题,主要讲解了什么是最大子数组问题,如何利用分治算法解决最大子...

  • 算法-分治最大子序和问题

    分治[https://baike.baidu.com/item/%E5%88%86%E6%B2%BB/302963...

  • 2018-05-24

    算法导论,分治算法,最大子数组问题。python ,代码抄袭,Dacixie的博客--https://blog.c...

  • 最长连续子序和问题

    0X00 算法总结 最大子序和 53. 最大子序和 这是一道非常经典的 dp 问题, 以最大子序和的最后一个数字来...

  • 【5月】LeetCode:我怎么还是这么菜

    5.3 题目链接 53. 最大子序和 很喜欢的解法(DP) 官方解(分治) 参考题解:最大子序和 但是仔细观察「方...

  • leetcode 刷题初体验

    开始喜欢上刷题,也愿意在一个问题上不断寻求最优解比如求最大子序和这道题从O(n2)到O(n)再到分治法求解(分治法...

  • 分治算法解最大子序列和问题

    最大子序列和问题 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最...

  • 分治策略对数组进行排序(二分排序算法)

    分治策略对数组进行排序(二分排序算法) 今天我来熟悉巩固一下分治算法对数组进行排序,分治问题就是把复杂的大问题拆解...

  • 最大子数组问题

    最近在看算法导论,看到计算最大子数组问题,于是写了一个iOS版本的。 利用分治策略,逐层寻找 最大子数组存在三种情...

  • 算法-理解动态规划

    算法-动态规划(1)最大子序和问题[/p/7e787a287876]算法-动态规划(2)最长公共子串[/p/7ba...

网友评论

      本文标题:算法-分治最大子序和问题

      本文链接:https://www.haomeiwen.com/subject/toxwoktx.html