最大子数组问题的递归和非递归(线性时间)代码

//**********最大子数组问题************void CrossingMaxSubArray(const vector&vec,int low,int mid,int high,int &left,int &right,int &max){//求跨越mid的最大子数组和,low是起点,mid是跨越的中心,high是终点,left是要得到最大子数组的起点,right是要得到//最大子数组的终点,max是要得到最大子数组的值int left_max = INT_MIN, right_max = INT_MIN;int sum = 0;for (int i = mid; i >= low; i--)//左边到mid的最大连续数组之和{sum = sum + vec[i];if (sum > left_max){left_max = sum;left = i;}}sum = 0;for (int j = mid + 1; j <= high; j++)//mid到右边最大连续数组之和{sum = sum + vec[j];if (sum > right_max){right_max = sum;right = j;}}max = left_max + right_max;//加起来,就是跨越mid的最大数组之和}void MaxSubArraySum(const vector &vec, int low, int high, int &start, int &end, int &max){//求最大子数组和的主函数,这是递归的!!//low是vec起点,high是vec终点,start是结果的起点,end是结果的终点,max是结果if (low == high){start = low;end = high;max = vec[low];}else{int mid = (low + high) / 2;int left_start = 0, left_end = 0, left_max = 0;MaxSubArraySum(vec, low, mid, left_start, left_end, left_max);int right_start = 0, right_end = 0, right_max = 0;MaxSubArraySum(vec, mid + 1, high, right_start, right_end, right_max);int crossing_start = 0, crossing_end = 0, crossing_max = 0;CrossingMaxSubArray(vec, low, mid, high, crossing_start, crossing_end, crossing_max);if (left_max >= right_max&&left_max >= crossing_max){start = left_start;end = left_end;max = left_max;}else if (right_max >= left_max&&right_max >= crossing_max){start = right_start;end = right_end;max = right_max;}else{start = crossing_start;end = crossing_end;max = crossing_max;}}}void GetMaxSubSum(const vector&vec)//非递归!也是最大子数组求和,不过只需要o(n),不需要递归和求出所有的情况进行比较{int k = 0, neg_ret = vec[0], start = 0, end = 0, sub_max = INT_MIN;for (; k < vec.size() && vec[k] <= 0; k++)//找到第一个大于0的,用k保存下标{if (vec[k] > neg_ret){neg_ret = vec[k];start = k;}}if (k == vec.size() - 1)//若找不到,返回最大一个负数{cout << start << " : " << neg_ret;return;}else//若找到{int sum = 0; start = k; int temp_start = k;for (int i = k; i < vec.size(); i++){sum = sum + vec[i];if (sum>sub_max)//若和大于sub_max,则保存并记录其下标{start = temp_start;//确定临时的起点可以成为最终的起点sub_max = sum;end = i;}if (sum < 0)//若小于0,则重新开始起点,并保留重新开始的起点,但起点不一定是最终的起点,还要经过上面的判断{sum = 0;if (i + 1 < vec.size())temp_start = i+1;}}cout << "开始:" << start << " 结束: " << end << " 最大值:" << sub_max << endl;}}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值