leecode 解题总结:363. Max Sum of Rectangle No Larger Than K

来源:互联网 发布:看不见的城市 知乎 编辑:程序博客网 时间:2024/06/06 01:38
#include <iostream>#include <stdio.h>#include <vector>#include <string>#include <set>using namespace std;/*问题:输入: 2 3(行和列) 1 -2 3 -4 5 6 3 59 -8 1 3 -2-3 7 6 -2 46 -4 -4 8 -7输出: 12-2 35 6199 -8 1 3-3 7 6 -26 -4 -4 8*///求一维子数组最大连续和int maxSubArray(vector<int>& nums){if(nums.empty()){return 0;}int size = nums.size();int sum = 0;int maxSum = 0;for(int i = 0 ; i  < size ; i++){sum = max(nums.at(i) , sum + nums.at(i));maxSum = max(maxSum , sum);}return maxSum;}//求一维子数组中最大连续和<k的最大值,先不断求累加和数组,然后//设需要找到的数为val , 即val < k 且val是最接近的,等同于求这样的累加和的位置//寻找之前的累加和val > 当前元素的累加和curSum  - k 的位置,然后找到val对应位置为p,用curSum - val,即可得到位置p到当前位置累加和<k的最大值//即val (min) > curSum - k, curSum - val(min) < kint maxSubArray_LessK(vector<int>& nums , int k){if(nums.empty()){return 0;}int curSum = 0 ;int best = 0;int size = nums.size();set<int> sums;for(int i = 0 ; i < size ; i++){curSum += nums.at(i);auto it = sums.upper_bound(curSum - k);//找到前面某元素的累加和略大于curSum-k中的最小值val,从而保证该元素与直到当前元素的累加和(curSum - val)略小于kif(it != sums.end() ){best = max(best , curSum - *it);}sums.insert(curSum);}return best;}int maxSubArray_NoMoreThanK(vector<int>& nums , int k){if(nums.empty()){return 0;}int curSum = 0 ;int best = INT_MIN;int size = nums.size();set<int> sums;sums.insert(0);//确保如果当前元素的累加和 < k,那么当前元素的累加和是一个解for(int i = 0 ; i < size ; i++){curSum += nums.at(i);auto it = sums.lower_bound(curSum - k);//找到前面某元素的累加和略大于curSum-k中的最小值val,从而保证该元素与直到当前元素的累加和(curSum - val)略小于kif(it != sums.end() ){best = max(best , curSum - *it);}sums.insert(curSum);}return best;}class Solution {public:    int maxSumSubmatrix(vector<vector<int>>& matrix, int k)     {    if(matrix.empty())    {    return 0;    }    int row = matrix.size();    int col = matrix.at(0).size();    int maxSum = INT_MIN;    for(int i = 0 ; i < col ; i++)    {    vector<int> nums(row , 0);    for(int j = i ; j < col ; j++)    {    set<int> sums;    sums.insert(0);//用于插入累加和元素    int curSum = 0;    int curMax = INT_MIN;    //计算从第i列到第j列中,每一行的元素和,将所有每一行的元素和作为一维子数组,然后求该子数组最大连续和    for(int x = 0; x < row ; x++)    {    //累加了上一列中同一行的元素    nums.at(x) += matrix.at(x).at(j);    curSum += nums.at(x);//计算累加和    auto it = sums.lower_bound(curSum - k);//寻找VALmin >= curSum - k ,那么curSum - VALmin <= k,计算出从寻找位置到当前位置最接近k的累加和    if(it != sums.end())    {    curMax = max(curMax , curSum - *it);    }    sums.insert(curSum);    }    maxSum = max(maxSum , curMax);    }    }    return maxSum;    }};//求二维连续子矩阵的最大和,采用遍历当前行,尝试将当前行及其以下部分的行中,每一列元素累加,转化为求一维中最大连续子数组之和int maxSubMatrix(vector<vector<int> >& matrix){if(matrix.empty()){return 0;}int row = matrix.size();int col = matrix.at(0).size();int maxSum = INT_MIN;for(int i = 0 ; i < row ; i++){vector<int> nums(col , 0);for(int j = i ; j < row ; j++){//计算从第i行到第j行中,每一列的元素和,将所有每一列的元素和作为一维子数组,然后求该子数组最大连续和for(int k = 0; k < col ; k++){//累加了上一行中同一列的元素nums.at(k) += matrix.at(j).at(k);}//求连续几行之间的最大连续和int sum = maxSubArray(nums);maxSum = max(maxSum , sum);}}return maxSum;}//以列主要计算方面,将两列之间同一行的元素累加,转化为一维数组求最大连续和,行n,列m,时间复杂度为O(m^2 * n)int maxSubMatrix_BaseColumn(vector<vector<int> >& matrix){if(matrix.empty()){return 0;}int row = matrix.size();int col = matrix.at(0).size();int maxSum = INT_MIN;for(int i = 0 ; i < col ; i++){vector<int> nums(row , 0);for(int j = i ; j < col ; j++){//计算从第i列到第j列中,每一行的元素和,将所有每一行的元素和作为一维子数组,然后求该子数组最大连续和for(int k = 0; k < row ; k++){//累加了上一列中同一行的元素nums.at(k) += matrix.at(k).at(j);}//求连续几行之间的最大连续和int sum = maxSubArray(nums);maxSum = max(maxSum , sum);}}return maxSum;}void process(){ vector<vector<int> > matrix; int value; int row; int col; int result; while(cin >> row >> col ) { matrix.clear(); for(int i = 0 ; i < row ; i++) { vector<int> nums; for(int j = 0 ; j < col ; j++) {cin >> value;nums.push_back(value); } matrix.push_back(nums); } result = maxSubMatrix_BaseColumn(matrix); cout << result << endl;; }}void test(){set<int> setNum;setNum.insert(1);int k = 10;int curNum = 1;auto it = setNum.lower_bound(curNum - k);int best = 0;if(it != setNum.end()){best = max(best , curNum - *it);}setNum.insert(curNum);}int main(int argc , char* argv[]){process();//test();getchar();return 0;}

0 0
原创粉丝点击