1. 程式人生 > >最大子列和(參考浙大-資料結構-MOOC)

最大子列和(參考浙大-資料結構-MOOC)

參考中國大學Mooc (浙江大學)->資料結構

我把陳越姥姥講的最大子列和記錄一下,以備不時之需.

"最大子列和" 問題

給一個數組,讓求出其中所有子列資料的和的Max 值.

1.暴力求解

拿到這個問題的第一瞬間想到的幾乎都是暴力,

  遍歷所有的子序列,找到其中最大值

//暴力求解
int MaxSubseqSum1(int A[], int n)
{
    int ThisSum, MaxSum = 0;
    int i,j,k;
    //找出所有子列
    for (i = 0; i < n; i++)
    {
        for (j = i; j < n; j++)
        {
            ThisSum = 0;
            for(k = i; k <= j; k++)
            {
                ThisSum += a[k];
            }// 求子列和
            if(ThisSum > MaxSum)
            {
                int t = ThisSum;
                ThisSum = MaxSum;
                MaxSum = t;
            }
        }
    }
    return MaxSum;
}

優點:特別容易被人理解,特別簡單

缺點:時間複雜度N的立方,太慢了

2.暴力的改進版本

仔細分析第一種方法,可以得到,最內層 的 k 迴圈,完全可以通過簡單的變化消失掉.

即:建立在 j 迴圈基礎,消除 k 迴圈

//對暴力的簡單改進
int MaxSubseqSum1(int A[], int n)
{
    int ThisSum, MaxSum = 0;
    int i,j,k;
    //找出所有子列
    for (i = 0; i < n; i++)
    {
        ThisSum = 0;
        for (j = i; j < n; j++)
        {//此處使用累加,消除掉 k 迴圈
            ThisSum += a[j];
            if(ThisSum > MaxSum)
            {
                int t = ThisSum;
                ThisSum = MaxSum;
                MaxSum = t;
            }
        }
    }
    return MaxSum;
}

時間複雜:N的平方

較第一種改進較大.

3. 二分

int Max3( int A, int B, int C )
{ /* 返回3個整數中的最大值 */
    return A > B ? A > C ? A : C : B > C ? B : C;
}
 
int DivideAndConquer( int List[], int left, int right )
{ /* 分治法求List[left]到List[right]的最大子列和 */
    int MaxLeftSum, MaxRightSum; /* 存放左右子問題的解 */
    int MaxLeftBorderSum, MaxRightBorderSum; /*存放跨分界線的結果*/
 
    int LeftBorderSum, RightBorderSum;
    int center, i;
 
    if( left == right )  { /* 遞迴的終止條件,子列只有1個數字 */
        if( List[left] > 0 )  return List[left];
        else return 0;
    }
 
    /* 下面是"分"的過程 */
    center = ( left + right ) / 2; /* 找到中分點 */
    /* 遞迴求得兩邊子列的最大和 */
    MaxLeftSum = DivideAndConquer( List, left, center );
    MaxRightSum = DivideAndConquer( List, center+1, right );
 
    /* 下面求跨分界線的最大子列和 */
    MaxLeftBorderSum = 0; LeftBorderSum = 0;
    for( i=center; i>=left; i-- ) { /* 從中線向左掃描 */
        LeftBorderSum += List[i];
        if( LeftBorderSum > MaxLeftBorderSum )
            MaxLeftBorderSum = LeftBorderSum;
    } /* 左邊掃描結束 */
 
    MaxRightBorderSum = 0; RightBorderSum = 0;
    for( i=center+1; i<=right; i++ ) { /* 從中線向右掃描 */
        RightBorderSum += List[i];
        if( RightBorderSum > MaxRightBorderSum )
            MaxRightBorderSum = RightBorderSum;
    } /* 右邊掃描結束 */
 
    /* 下面返回"治"的結果 */
    return Max3( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );
}
 
int MaxSubseqSum3( int List[], int N )
{ /* 保持與前2種演算法相同的函式介面 */
    return DivideAndConquer( List, 0, N-1 );
}

時間複雜度:N*log(N)

但是理論較難,程式碼晦澀.

4.線上處理

一個牛逼的演算法

從前到後進行一次遍歷,找到其中最大值,但是隻要某一段子列和為0,即拋棄此時的ThisSum,重新置為0

//線上處理法
int MaxSubseqSum4(int A[], int n)
{
    int ThisSum = 0, MaxSum = 0;
    int i;
    for(i = 0; i<n; i++)
    {
        ThisSum += a[i];
        if(ThisSum >MaxSum)
        {
            MaxSum= ThisSum;
        }
        else if(ThisSum <0){
            ThisSum = 0;
        }
        
    }
    return MaxSum;
}

時間: N

缺點: 總有人懷疑其正確性(講真,我還覺得這個演算法有問題...)

相關推薦

大子(參考浙大-資料結構-MOOC)

參考中國大學Mooc (浙江大學)->資料結構 我把陳越姥姥講的最大子列和記錄一下,以備不時之需. "最大子列和" 問題 給一個數組,讓求出其中所有子列資料的和的Max 值. 1.暴力求解 拿到這個問題的第一瞬間想到的幾乎都是暴力,   遍歷所有的子序列,找到其

mooc浙大資料結構PTA習題之大子問題2(線上處理)

01-複雜度2 Maximum Subsequence Sum(25 分) Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A continuous subsequence is defined to

資料結構大子

#include <stdlib.h> #include <stdio.h> int MaxSubseqSum(int a[],int N) {     int i,ThisSum = 0,MaxSum = 0;    &nb

中國大學MOOC-陳越、何欽銘-資料結構-2018秋 01-複雜度1 大子問題 (20 分)

01-複雜度1 最大子列和問題 (20 分) 給定K個整陣列成的序列{ N​1​​, N​2​​, ..., N​K​​ },“連續子列”被定義為{ N​i​​, N​i+1​​, ..., N​j​​ },其中 1≤i≤j≤K。“最大子列和”則被定義為所有連續子列元素的和

MOOC資料結構課程 題集01 大子問題

01-複雜度1 最大子列和問題 (20 分) 給定K個整陣列成的序列{ N​1​​, N​2​​, ..., N​K​​ },“連續子列”被定義為{ N​i​​, N​i+1​​, ..., N​j​​ },其中 1≤i≤j≤K。“最大子列和”則被定義為所有連續子列

PTA資料結構與演算法題目集(中文)5-1 大子問題 (20分)

給定KK個整陣列成的序列{ N_1N​1​​, N_2N​2​​, ..., N_KN​K​​ },“連續子列”被定義為{ N_iN​i​​, N_{i+1}N​i+1​​, ..., N_jN​j​​ },其中 1 \le i \le j \le K1≤i≤j≤

PTA 資料結構題目(1):大子問題(分而治之、線上處理演算法)

題目來源: 問題描述: 問題分析: 對於一般的問題,原始解 都能通過一種 蠻力演算法,即窮舉法的思想得到。這題也不例外。 如果我們,把輸入的陣列,所有的子列都歷遍,並從中找出最大,即可得出我們的演算法。也就是版本一。 學習要點: 1、如何

PAT資料結構_01-複雜度1 大子問題

題目:https://pta.patest.cn/pta/test/15/exam/4/question/709 #include <iostream> using namespace std; int MaxSubseqSum2(int A[], in

MOOC 資料結構 大子問題

原題:最大子列和 問題描述 “最大子列和”則被定義為所有連續子列元素的和中最大者。例如給定序列{ -2, 11, -4, 13, -5, -2 },其連續子列{ 11, -4, 13 }有最大的和20。現要求你編寫程式,計算給定整數序列的最大子列和。

資料結構學習筆記(1):Maximum Subsequence Sum大子

問題思路分析:就是課堂上所講過的最大子列和問題,不過需要輸出子列頭和尾的項根據網上的資料,摹寫程式碼為具體實現:#include<iostream> using namespace std; int main (){ int N ; cin >>

大子問題(浙江大學資料結構

//第三種,分治法  int Max(int A,int B,int C) {if(A>B&&A>C)return A;elseif(B>A&&B>C)return B;elsereturn C;  }  int PartSum(int A[],int

【中國大學MOOC-陳越、何欽銘-資料結構-2017秋】大子問題

給定K個整陣列成的序列{ N​1​​, N​2​​, ..., N​K​​ },“連續子列”被定義為{ N​i​​, N​i+1​​, ..., N​j​​ },其中 1≤i≤j≤K。“最大子列和”則被定義為所有連續子列元素的和中最大者。例如給定序列{ -2, 11, -4, 13, -5, -2

PAT 資料結構 01-複雜度1. 大子問題(20)

給定K個整陣列成的序列{ N1, N2, ..., NK },“連續子列”被定義為{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。“最大子列和

數據結構(一)-----4種方法求大子

include iss 需要 中間 () log 完整 font sso 數據結構(一)-----4種方法求最大子列和 1、暴力算法 /* 作者:mys 功能:求最大子列和 日期:2018/7/23 */ #include<stdio.h> #include&l

基礎數據結構應用——大子問題

pan nts -h 不同 ... printf fine () script 給定K個整數組成的序列{ N?1??, N?2??, ..., N?K?? },“連續子列”被定義為{ N?i??, N?i+1??, ..., N?j?? },其中 1。“最大子列和”則被定義

應用實例——大子問題

[] str else -s 給定 復雜 lin wid 工作流 題目描述:給定N個整數的序列{A1,A2,...,AN},求函數f(i,j)=max{0,ΣAk(i<=k<=j)}的最大值 算法1: 1 int MaxSubseqSum1(int A[],

大子(在線處理,復雜度O(n))

spa 最大子列和 pts 最大 int nts ups script 程序 #include<stdio.h> int main(){ int k,num,sum=0,Max=0; scanf("%d",&k); while(k--){ s

PATtest1.3:大子

題目源於:https://pintia.cn/problem-sets/16/problems/663 題目要求:輸入一個數列,求其最大子列和。   問題反饋:1.部分C++程式碼不是很熟練               &

大子

int MaxSubSeqSum(int arr[], int n) { int currentSum, maxSum; currentSum = maxSum = 0; for(int i=0; i<n; i++) { curr

演算法學習——大子問題

參考視訊: 中國大學mooc——浙江大學——資料結構——陳越、何欽銘 問題描述: 求取陣列中最大連續子序列和,例如給定陣列為A={1, 3, -2, 4, -5}, 則最大連續子序列和為6,即1+3+(-2)+ 4 = 6。 演算法一 int MaxSubseqSu