文章目录
- [53. 最大子数组和(LCR 161 连续天数的最高销售额)](#53. 最大子数组和(LCR 161 连续天数的最高销售额))
- [85. 最大矩形](#85. 最大矩形)
- [187. 重复的DNA序列](#187. 重复的DNA序列)
- [209. 长度最小的子数组](#209. 长度最小的子数组)
- [238. 除自身以外数组的乘积](#238. 除自身以外数组的乘积)
- [363. 矩形区域不超过 K 的最大数值和](#363. 矩形区域不超过 K 的最大数值和)
- [396. 旋转函数](#396. 旋转函数)
53. 最大子数组和(LCR 161 连续天数的最高销售额)
线性DP
cpp
class Solution {
public:
int maxSubArray(vector<int>& nums) {
for (int i=1;i<nums.size();i++)
if (nums[i-1]>0)
nums[i]+=nums[i-1];
int result=INT_MIN;
for (int i=0;i<nums.size();i++)
if (nums[i]>result)
result=nums[i];
return result;
}
};
前缀和
cpp
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int * lb=new int [nums.size()+1];lb[0]=0;
for (int i=1;i<nums.size()+1;i++)
lb[i]=lb[i-1]+nums[i-1];
int min_value=0,result=INT_MIN;
for (int i=1;i<nums.size()+1;i++)
{
int result_temp=lb[i]-min_value;
if (result_temp>result) result=result_temp;
if (lb[i]<min_value) min_value=lb[i];
}
delete [] lb;
return result;
}
};
85. 最大矩形
单调栈那里已经做过了。
cpp
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
vector<vector<int>> my_matrix(matrix.size(),vector<int> (matrix[0].size()));
for (int i=0;i<matrix[0].size();i++)
my_matrix[0][i]=(matrix[0][i]-'0');
for (int i=1;i<matrix.size();i++)
for (int j=0;j<matrix[0].size();j++)
my_matrix[i][j]=matrix[i][j]=='0'?0:my_matrix[i-1][j]+(matrix[i][j]-'0');
int result=0;
for (int i=0;i<my_matrix.size();i++)
{
int result_temp=fc(my_matrix[i]);
if (result_temp>result) result=result_temp;
}
return result;
}
int fc(const vector<int> & heights)
{
vector<int> my_vector1(heights.size(),-1);
stack<int> my_stack1;
for (int i=0;i<heights.size();i++)
{
while (!my_stack1.empty() and heights[i]<heights[my_stack1.top()])
{
my_vector1[my_stack1.top()]=i;my_stack1.pop();
}
my_stack1.push(i);
}
vector<int> my_vector2(heights.size(),-1);
stack<int> my_stack2;
for (int i=heights.size()-1;i>=0;i--)
{
while (!my_stack2.empty() and heights[i]<heights[my_stack2.top()])
{
my_vector2[my_stack2.top()]=i;my_stack2.pop();
}
my_stack2.push(i);
}
int result=0;
for (int i=0;i<heights.size();i++)
{
int r,l;
if (my_vector1[i]==-1) r=heights.size()-1-i;
else r=my_vector1[i]-1-i;
if (my_vector2[i]==-1) l=i;
else l=i-1-my_vector2[i];
int result_temp=heights[i]*(r+l+1);
if (result_temp>result) result=result_temp;
}
return result;
}
};
187. 重复的DNA序列
滑动窗口那里已经做过了。
不知道这道题跟前缀和有啥关系。
cpp
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
vector<string> lb;
if (s.size()<=10) return lb;
unordered_map<string,int> zd;
string s_new=s.substr(0,10);
zd[s_new]=1;
for (int i=10;i<s.size();i++)
{
s_new.erase(0,1);s_new+=s[i];
if (zd.find(s_new)==zd.end()) zd[s_new]=1;
else
{
if (zd[s_new]==1) lb.push_back(s_new);
zd[s_new]+=1;
}
}
return lb;
}
};
209. 长度最小的子数组
滑动窗口
cpp
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
if (nums[0]>=target) return 1;
int begin=0,length=1,value=nums[0],result=INT_MAX;
while (begin-1+length<nums.size())
if (value<target)
{
if (begin+length==nums.size()) break;
length+=1;value+=nums[begin+length-1];
}
else
{
if (length<result) result=length;
value-=nums[begin];begin+=1;length-=1;
}
return result==INT_MAX?0:result;
}
};
前缀和
cpp
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int * lb=new int [nums.size()+1];lb[0]=0;
for (int i=0;i<nums.size();i++)
lb[i+1]=lb[i]+nums[i];
int result=INT_MAX;
for (int i=0;i<nums.size()+1;i++)
{
int l=i,r=nums.size(),value=lb[i]+target;
if (value>lb[nums.size()]) break;
while (l<=r)
{
int m=l+(r-l)/2;
if (lb[m]<value) l=m+1;
else if (m==i or lb[m-1]<value)
{
if (m-i+1<result) result=m-i+1;
break;
}
else r=m-1;
}
}
return result==INT_MAX?0:result-1;
}
};
238. 除自身以外数组的乘积
前缀积、后缀积
cpp
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
vector<int> lb1(nums.size());lb1[0]=nums[0];
for (int i=1;i<nums.size();i++)
lb1[i]=lb1[i-1]*nums[i];
vector<int> lb2(nums.size());lb2[nums.size()-1]=nums[nums.size()-1];
for (int i=nums.size()-2;i>=0;i--)
lb2[i]=lb2[i+1]*nums[i];
vector<int> lb3(nums.size());
for (int i=0;i<nums.size();i++)
{
int l=i==0?1:lb1[i-1];
int r=i==nums.size()-1?1:lb2[i+1];
lb3[i]=l*r;
}
return lb3;
}
};
她的有些题涉及到了其他我没有学的知识。这些题暂时不做吧,等我学完了再在对应部分补充。主要是我真心不会,已经开摆了。
363. 矩形区域不超过 K 的最大数值和
下面代码的时间复杂度为 O ( m 2 n 2 ) O(m^2n^2) O(m2n2)。不想优化了,反正能过而且n最大也就100,开摆开摆。官方题解代码的时间复杂度为 O ( m 2 n l o g 2 n ) O(m^2 nlog_2^n) O(m2nlog2n),应该是哪里用了一下二分查找。唉,不想去想了,大脑已经动不了了。
cpp
class Solution {
public:
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
int m=matrix.size()+1,n=matrix[0].size()+1;
int * * lb=new int * [m];
for (int i=0;i<m;i++)
{
lb[i]=new int [n];
for (int j=0;j<n;j++)
lb[i][j]=0;
}
for (int i=1;i<m;i++)
for (int j=1;j<n;j++)
{
lb[i][j]=lb[i][j-1]+matrix[i-1][j-1];
}
for (int j=1;j<n;j++)
for (int i=1;i<m;i++)
{
lb[i][j]=lb[i-1][j]+lb[i][j];
}
int result=INT_MIN;
for (int i=1;i<m;i++)
for (int j=1;j<n;j++)
for (int length=1;length<m-i+1;length++)
for (int width=1;width<n-j+1;width++)
{
int result_temp=lb[i+length-1][j+width-1]+lb[i-1][j-1]-
lb[i+length-1][j-1]-lb[i-1][j+width-1];
if (result_temp==k) return k;
if (result_temp<k and result_temp>result)
result=result_temp;
}
for (int i=0;i<m;i++)
delete [] lb[i];
return result;
}
};
396. 旋转函数
滑动窗口那里已经做过了。
前缀积、后缀积
cpp
class Solution {
public:
int maxRotateFunction(vector<int>& nums) {
int count=0;
for (int x:nums) count+=x;
int f0=0;
for (int i=0;i<nums.size();i++)
f0+=i*nums[i];
int result=f0;
for (int i=1;i<nums.size();i++)
{
f0=f0+count-nums[nums.size()-i]*nums.size();
if (f0>result) result=f0;
}
return result;
}
};
唉,那就这样吧,不做了。