(一)返回数组中子数组的最大累加和并打印子数组

【题目】给定一个数组arr,返回子数组的最大累加和,并打印子数组
【例如】arr = [1,-2,3,5,-2,6,-1],[3,5,-2,6]可以累加出最大和12,输出12,并打印该子数组

【解题思路】cur累加成为负数清零重新累加,maxNum记录cur的最大值

  • 若arr中没有正数,产生的最大累加和一定是数组中的最大值;
  • 若arr中有正数,从左到右遍历arr,变量cur记录每一步的累加和。若cur<0时,那么累加的这一部分不能作为产生最大累加值和的子数组的左边部分,此时令cur=0,表示重新从下一个数开始累加。cur>=0时,每次累加都可能是最大的累加和,用变量maxNum记录cur出现的的最大值

【C++代码】

#include <iostream>
#include <limits.h>
#include <stack>
#include <algorithm>
using namespace std;

int getMaxSum(int arr[],int len,vector<int> &res){
    
    
    if(arr == NULL || len == 0){
    
    
        return 0;
    }    
    stack<int> st;
    int maxNum = INT_MIN;//记录cur的最大值
    int cur = 0;//记录每步累加和
    int start = 0;//记录最大子数组起始下标 在数组arr中的位置
    int end = 0;//记录最大子数组末尾下标 在数组arr中的位置
    for(int i = 0;i != len;i++){
    
    
        cur += arr[i];
        if(cur > maxNum){
    
    
            maxNum = cur;
            end = i;  //更新最大子数组末尾下标,只有cur比前面的最大值更大时才更新
        }      
        cur = cur < 0 ? 0 : cur;
        if(cur == 0){
    
       //当cur==0时利用栈记录最大子数组的起始下标,因为cur<0时起始坐标会改变
            st.push(i);    
        }   
    }
    while(!st.empty()){
    
    //判断哪个才是最终的起始下标,起始下标值不能大于末尾下标值,且为最新更新的下标,所以用栈实现
        start = st.top();
        if(start < end)
            break;
        st.pop();
    }
    start++;
    
    //打印子数组
    cout << "最大累加和子数组:";
    for(int i = start;i <= end;i++){
    
    
        cout << arr[i] << " ";
    }
    cout << endl;    
    return maxNum;    
}

int main(){
    
    
    vector<int> res;
    int arr[] = {
    
    1,-2,3,5,-20,6,-1};
    //int arr[] = {-11,-2,-33,-4,-9,-3};
    int len = sizeof(arr)/sizeof(arr[0]);
    cout << "最大累加和为:" << getMaxSum(arr,len,res) << endl;
    return 0;    
}

【参考】程序员代码面试指南——左程云

Guess you like

Origin blog.csdn.net/weixin_44515978/article/details/121891678