zoukankan      html  css  js  c++  java
  • 逐步优化求解最大子序列和

    求解最大子序列和

    tag: 数据结构与算法


    最大子序列和问题:

    给定序列A1, A2,... AN, 求最大的子序列和。
    例如 :
      对于序列4, -3, 5, -2, -1, 2, 6, -2, 最大序列和为11(4 -3 + 5 - 2 - 1 + 2 + 6)

    算法一:

    利用两个循环,第一个循环把序列遍历一遍,第二个循环则从Ai累加到AN,每加一次判断一下是否大于之前的最大子序列和:

    int maxSubsequenceSum1 (const int arr[], int n) {
      int maxSum = 0;
      int temp;
    
      for (int i = 0; i < n; i++) {
        temp = 0;
    
        for (int j = i; j < n; j++) {
          temp += arr[j];
          if (temp > maxSum)
    	maxSum = temp;
        }
      }
    
      return maxSum;
    }
    

    时间复杂度:O(n2

    算法二:

    首先把序列从中间一分为二, 则最大子序列和的存在有三种情况:

    1. 全在左边的子序列
    2. 全在右边的子序列
    3. 处在中间
      对于第一和第二种情况,只需要递归调用求解函数,对于第三种情况则要分别求出从中间出发,向左边和向右边各自的最大子序列和。
    int max(int a, int b, int c) {
      int max;
    
      if (a > b)
        max = a;
      else 
        max = b;
    
      if (c > max)
        max = c;
    
      return max;
    }
    
    int maxSubsequenceSum2 (const int arr[], int begin, int end) {
      int maxLeftSum, maxRightSum, maxLeftCenterSum, maxRightCenterSum, center, temp;
    
      if (begin >= end) {
        if (arr[begin] > 0)
          return arr[begin];
        else
          return 0;
      }
    
      center = (begin+end)/2;
      maxLeftSum = maxSubsequenceSum2(arr, begin, center);
      maxRightSum = maxSubsequenceSum2(arr, center+1, end);
    
      maxLeftCenterSum = 0;
      temp = 0;
      for (int i = center; i >= begin; i--) {
        temp += arr[i];
    
        if (temp > maxLeftCenterSum)
          maxLeftCenterSum = temp;
      }
    
      maxRightCenterSum = 0;
      temp = 0;
      for (int i = center+1; i <= end; i++) {
        temp += arr[i];
    
        if (temp > maxRightCenterSum)
          maxRightCenterSum = temp;
      }
    
      return max(maxLeftSum, maxRightSum, (maxLeftCenterSum+maxRightCenterSum));
    }
    

    时间复杂度:O(nlogn)

    算法三:

    累加序列,若发现当前序列和大于之前最大序列和,则替换.若发现当前序列和小于0,则将当前序列和置换成0,相当于把前面的序列都舍弃掉.

    int maxSubsequenceSum3(int arr[], int n) {
      int tempSum = 0, maxSum = 0;
    
      for (int i = 0; i < n; i++) {
        tempSum += arr[i];
        if (tempSum < 0)
          tempSum = 0;
        if (tempSum > maxSum)
          maxSum = tempSum;
      }
    
      return maxSum;    
    }
    

    时间复杂度:O(n)

  • 相关阅读:
    linux学习之linux的hostname修改详解《转》
    不想作死系列--win7远程linux桌面之vncserver
    不想作死系列---virtualbox最小化安装centos6.5
    基于支持向量机的车牌识别-- opencv2.4.7+vs2012环境搭建
    python文件的中文处理以及个人思路
    haskell学习笔记<1>--基本语法
    提醒
    C语言矩阵传递给函数的方法
    0x01数据结构——C语言实现(二叉查找树)
    0x01数据结构——C语言实现(二叉树)
  • 原文地址:https://www.cnblogs.com/bgmind/p/3959193.html
Copyright © 2011-2022 走看看