007求数组中子数组最大的和
来源:互联网 发布:淘宝买的steam游戏礼物 编辑:程序博客网 时间:2024/05/06 05:13
题目描述:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
思路一,暴力法。通过三层循环,找出所有子数组,求和,比较,得出最大和,时间复杂度O(n^3)
int maxsum01(int array[],int n){int sum = 0;int max = 0;for(int i=0;i<n;i++){for(int j=i;j<n;j++){for(int k=i;k<=j;k++){sum += array[k];}if(sum>max)max = sum;sum=0;}}return max;}思路二,线性遍历数组,如果将当前元素加入之后sum<=0,说明截至到该元素,往后再加元素也不会达到子数组和最大,此时将sum更换为下一个元素,每次加入新元素之后都会与现有的max进行比较,以保留最大值。时间复杂度O(n)
int maxsum02(int array[],int n){int sum = 0;int max = array[0];for(int i=0;i<n;i++){if(sum>=0){sum += array[i];}else{sum = array[i];}if(sum>max)max = sum;}return max;}
当数组元素全为负数时,返回数组中最大元素值。
思路三,利用动态规划的方法
设sum[i] 为前i个元素中,包含第i个元素且和最大的连续子数组,result 为已找到的子数组中和最大的。对第i+1个元素有两种选择:做为新子数组的第一个元素、放入前面找到的子数组。
sum[i+1] = max(a[i+1], sum[i] + a[i+1])
result = max(result, sum[i])
int maxsum03(int array[],int n){int sum = array[0];int max = array[0];for(int i=1;i<n;i++){sum += array[i];if(sum < array[i])sum = array[i];if(max<sum)max = sum;}return max;}
问题扩展
- 如果数组是二维数组,同样要你求最大子数组的和列?
- 如果是要你求子数组的最大乘积列?《???》
- 如果同时要求输出子段的开始和结束列?
思路是使用线性扫描,使用空间换时间,用数组b[i]保存a[0]*...*a[i-1]*a[i+1]*...a[n-1]。代码如下:
int makeArray(int a[],int b[],int n){b[0]=1;for(int i=1;i<n;i++){b[0] *= a[i-1];b[i] = b[0];//b[i]=a[0]*...*a[i-1]}b[0]=1;for(int j=n-2;j>0;j--){b[0] *= a[j+1];b[j] *= b[0];//b[j]=a[n-1]*...*a[j+1]*a[j-1]*...*a[0]}b[0] *= a[1];int max = -2147483647 - 1;cout<<endl;for(int k=0;k<n;k++){cout<<b[k]<<endl;if(max < b[k])max = b[k];}cout<<endl;return max;}
举一反三
1 给定整型数组,其中每个元素表示木板的高度,木板的宽度都相同,求这些木板拼出的最大矩形的面积。并分析时间复杂度。
此题类似leetcode里面关于连通器的题,需要明确的是高度可能为0,长度最长的矩形并不一定是最大矩形,还需要考虑高度很高,但长度较短的矩形。如[5,4,3,2,4,5,0,7,8,4,6]中最大矩形的高度是[7,8,4,6]组成的矩形,面积为16。
解决思路:使用分治递归的方法,即在[start,end]区域计算出矩形的面积,计算左侧的面积,计算右侧的面积,找出三者中面积最大的,返回
//最大值 int MAX(int a,int b) { return a > b ? a : b; } //给定数组表示单位宽度木板的高,求最大矩形的面积 int MaxSquare(int*a,int start,int end,int &Max) { if(end < start) return 0; if(end == start) return a[end]; int minindex = start; for(int i = start;i <=end;i++)//每次求出区间的最小高度 if(a[i] < a[minindex]) minindex = i; int all = a[minindex] * (end - start +1);//以最小高度的最长矩形的面积 int lf = MaxSquare(a,start,minindex -1,Max);//左区域的最大面积 int rg = MaxSquare(a,minindex +1,end,Max);//右区域的最大面积 int t =MAX(all,MAX(lf,rg));//当前区间的最大面积 Max = MAX(Max,t); return t; } int MaxSquare(int*a,int n) { int minindex = 0; int max = 0; MaxSquare(a,0,n-1,max); return max; }
2、最大子矩阵和
一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值。如果所有数都是负数,就输出0。 例如:3*5的矩阵:
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
和最大的子矩阵是:
4 5
5 3
最后输出和的最大值17。
《
原题目给出的答案可能有问题,对于子矩阵
3 4 5
1 5 3
的值要比给出的矩阵的和要大
》
解决思路:在求最大子数组和的基础上,对于矩阵从i到j行,相加,得到一个数组,求出a[i][0-m]到a[j][0-m]之间和最大的子矩阵的和
int maxSubMatrix(int matrix[5][5],const int n,const int m){int i,j,k,max=0,sum=-10000;int b[101];for(i=0;i<n;i++){for(k=0;k<m;k++){b[k] =0;}for(j=i;j<n;j++){for(k=0;k<m;k++){b[k] += matrix[j][k];}max = maxsum03(b,m);if(max > sum){sum = max;}}}return sum;}
3、允许交换两个数的位置 求最大子数组和。(???)
// you can also use includes, for example:#include <algorithm>int help(vector<int> &a) { int n = a.size(); vector<int> f,g; f.resize(n); f[0] = a[0]; int now = a[0]; for (int i = 1; i < n; ++i) { now = max(now, a[i]); f[i] = max(a[i] + f[i - 1], now); } g.resize(n); g[n - 1] = a[n - 1]; int answer = a[n - 1]; for (int i = n - 2; i >= 0; --i) { g[i] = max(g[i + 1], 0) + a[i]; answer = max(answer, g[i]); } for (int i = 1; i < n; ++i) { answer = max(answer, g[i] - a[i] + f[i - 1]); } return answer;}int solution(vector<int> &A) { // write your code in C++11 int answer = help(A); for (int i = 0, j = A.size() - 1; i < j; ++i,--j) { swap(A[i],A[j]); } answer = max(answer,help(A)); return answer; }
- 求数组中子数组的最大和
- 007求数组中子数组最大的和
- 求二维数组中子数组和中最大的值,及子数组
- 【算法题】求数组中子数组的最大乘积
- 求一个数组中子数组中的和的最大值
- 查找数组中子数组最大和
- 数组中子数组的最大累乘积
- 求数组最大子数组的和
- 数组与矩阵---数组中子数组的最大累乘积
- 数组中子数组和的最大值
- 数组中子数组等于k的最大长度
- 编程之美--求数组中子数组之和的最大值
- 求子数组的最大和
- 面试---求子数组的最大和
- 求子数组的最大和
- 求子数组的最大和
- 求子数组的最大和
- 求子数组的最大和
- AppendMenu函数的使用方法,最好附例,谢了……
- vim配置文件
- 数据挖掘中易犯的11大错误
- 嘉扬CEO游学看世界
- 001:Sublime Text 2搭建成一个好用的IDE
- 007求数组中子数组最大的和
- maven 下载poi API 的 POM
- centos yum安装nginx php mysql
- 编译 chromium for android
- LeetCode OJ - Palindrome Number
- xception in thread "main" java.lang.AbstractMethodError: org.slf4j.impl.Log4jMDCAdapter.getCopyOfCon
- 用C/C++开发基于VLC SDK的视频播放器 开发环境搭建
- Myeclipse CheckStyle links安装
- Android 记录和恢复ListView滚动的位置的三种方法