微軟等公司數據結構面試題3

 

3.求子數組的最大和(數組)
題目:
輸入一個整形數組,數組裏有正數也有負數。
數組中連續的一個或多個整數組成一個子數組,每個子數組都有一個和。
求所有子數組的和的最大值。要求時間複雜度爲O(n)。

例如輸入的數組爲1, -2, 3, 10, -4, 7, 2, -5,和最大的子數組爲3, 10, -4, 7, 2,
因此輸出爲該子數組的和18。


 

#include <iostream>

 

class Array

{

public:

Array(int a[],int length):m_array(a),m_length(length) {}

void Findbest();

void Print();

private:

int  *m_array;

int m_left;

int m_right;

int m_length;

int m_nearLeft;

int m_nearRight;

int m_max;

int m_nearMax;

};

void Array::Findbest()

{

m_left = 0;

m_right = -1;

m_nearLeft = 0;

m_nearRight = -1;

m_max = m_nearMax = 0 ;

for (int i = 0 ; i < m_length ; i++ )

{

if ( m_array[i] >= 0  ) {

if ( m_nearRight + 1 == i ) {

m_nearMax += m_array[i] ;

m_nearRight = i ;

else {

m_nearLeft = m_nearRight = i;

m_nearMax = m_array[i] ;

}  // else if  ( m_nearRight +1 == i )

if (m_right + 1 == i) {

m_right = i;

m_max += m_array[i];

}

else {

if ( m_max < m_nearMax ) {

m_max = m_nearMax ;

m_left = m_nearLeft ;

m_right = m_nearRight ;

}

} //else if (m_right +1 == i)

}  //end if ( m_array[i] >= 0  ) 

else {

if ( m_nearRight + 1 == i && m_nearMax + m_array[i] > 0 ) {

m_nearMax += m_array[i] ;

m_nearRight = i ;

}

else {

m_nearLeft = m_nearRight = 0;

}

}  

}  //end of for

 

 

}

 

void Array::Print()

{

std::cout<<"left="<<m_left+1<<"  right="<<m_right+1<<std::endl;

std::cout<<"Total is "<<m_max<<std::endl;

for(int i = m_left ; i <=m_right ; i++ ) {

std::cout<<m_array[i]<<" ";

}

std::cout<<std::endl;

}

 

int main()

{

int t[]={-1,-2,3,10,-4,7,2,-5};

Array a(t,8);

a.Findbest();

a.Print();

getchar();

return 0;

}

 

 

 

利用動態規劃的思想:

當前a[i]的最大子數組等於 a[i-1]的最大子數組 + a[i]   a[i]>=0  a[i-1]的最大子數組右值下標爲i-1

                                    max (a[i-1]的最大子數組  or a[i]最靠近右邊大於零的子數組)  a[i]>=0 a[i-1]的最大子數組右值下標不爲i-1

 

 

當 a[i] <0 時 僅需要對  a[i]最靠近右邊大於零的子數組 進行處理即可:

當    a[i-1]最靠近右邊大於零的子數組 + a[i] >= 0 時 子數組增加

否則對子數組清空     

 

 

上面的思路比較複雜 下面的判斷簡化,只需要用最近的記錄的和和以前的最大值比較,如果記錄的最近的和小於0,則重新記錄

 

 

#include <iostream>

 

class Array

{

public:

Array(int a[],int length):m_array(a),m_length(length) {}

void Findbest();

void Print();

private:

int  *m_array;

int m_left;

int m_right;

int m_length;

int m_nearLeft;

int m_nearRight;

int m_max;

int m_nearMax;

};

void Array::Findbest()

{

m_left = 0;

m_right = -1;

m_nearLeft = 0;

m_nearRight = -1;

m_max = m_nearMax = 0 ;

for (int i = 0 ; i < m_length ; i++ )

{

 

m_nearMax += m_array[i];

m_nearRight++;

 

if (m_nearMax > 0)

{

 

if ( m_nearMax > m_max)

{

m_max = m_nearMax;

m_left = m_nearLeft;

m_right = m_nearRight;

}

 

}

else

{

m_nearMax = 0;

m_nearLeft =  i + 1 ;

m_nearRight = i;

}

 

}  //end of for

 

 

}

 

 

 

void Array::Print()

{

std::cout<<"left="<<m_left+1<<"  right="<<m_right+1<<std::endl;

std::cout<<"Total is "<<m_max<<std::endl;

for(int i = m_left ; i <=m_right ; i++ ) {

std::cout<<m_array[i]<<" ";

}

std::cout<<std::endl;

}

 

 

 

int main()

{

int t[]={-1,-2,3,10,-4,7,2,-5};

Array a(t,8);

a.Findbest();

a.Print();

getchar();

return 0;

}

 

發佈了24 篇原創文章 · 獲贊 1 · 訪問量 7854
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章