周赛第二题:
总结踩坑:
再比赛过程中写这个题的时候只想到了可以从选取的两数来划分三个区间,之后在两端或者中间区间内取数,这样做的时间复杂度在
n
3
n^3
n3 因而TLE了
正确解法:
可以首先预处理出任意两数乘积结果对应的的数目,将其存入hash表中(因为最大的乘积结果可能太大了,所以没用数组),之后任意组合乘积相同的两个数,即可;
代码:
class Solution {
public:
int tupleSameProduct(vector<int>& nums) {
unordered_map<long long,int> sto;
for(int i = 0;i<nums.size()-1;i++)
{
for(int j = i+1;j<nums.size();j++)
{
if(sto.count(nums[i]*nums[j]))
{
sto[nums[i]*nums[j]]++;
}
else
{
sto[nums[i]*nums[j]] = 1;
}
}
}
int count_n = 0;
for(auto c : sto)
{
count_n += c.second*(c.second-1)/2;
}
return count_n*8;
}
};
周赛第三题:
总结踩坑:
这题刚开始想的时候是想直接找出一个列的最优排序,其实我们是不可能直接找到的,在以后要学会将问题分解为小部分,从局部出发去求解全局的最优解。
正确解法:
可以首先假设只有一行,之后慢慢向下扩展,增加行数
这就需要我们构建出来一个二维矩阵来存储从每个位置连续的1的长度
对每列的高度进行从小到大进行排序,慢慢寻找最大的面积即可。
代码:
class Solution {
public:
int largestSubmatrix(vector<vector<int>>& matrix) {
int m = matrix.size(); //行
int n = matrix[0].size();//列
vector<vector<int>> up_sto(m,vector<int>(n,0));
for(int i = 0;i<m;i++)
{
for(int j = 0;j<n;j++)
{
if(matrix[i][j]==1)
{
up_sto[i][j] = (i==0?1:up_sto[i-1][j]+1);
}
}
}
vector<int> buf;
int res = 0;
for(int i = 0;i<m;i++)
{
buf.clear();
for(int j = 0;j<n;j++)
buf.push_back(up_sto[i][j]);
sort(buf.begin(),buf.end());
for(int k = 0;k<n;k++)
{
res = max(res,buf[k]*(n-k));
}
}
return res;
}
};