最大子列和(參考浙大-資料結構-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 { N1, N2, ..., NK }. 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個整陣列成的序列{ N1, N2, ..., NK },“連續子列”被定義為{ Ni, Ni+1, ..., Nj },其中 1≤i≤j≤K。“最大子列和”則被定義為所有連續子列元素的和
MOOC資料結構課程 題集01 最大子列和問題
01-複雜度1 最大子列和問題 (20 分) 給定K個整陣列成的序列{ N1, N2, ..., NK },“連續子列”被定義為{ Ni, Ni+1, ..., Nj },其中 1≤i≤j≤K。“最大子列和”則被定義為所有連續子列
PTA資料結構與演算法題目集(中文)5-1 最大子列和問題 (20分)
給定KK個整陣列成的序列{ N_1N1, N_2N2, ..., N_KNK },“連續子列”被定義為{ N_iNi, N_{i+1}Ni+1, ..., N_jNj },其中 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個整陣列成的序列{ N1, N2, ..., NK },“連續子列”被定義為{ Ni, Ni+1, ..., Nj },其中 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