比赛心得: 本次比赛的经历让我大致地了解到了力扣周赛的难度:主要是前两题比较简单、第三题难度加深、最后一题相比来说最难。随着难度层次的逐渐加深,知识点也逐渐增多,而且周赛涉及到的知识点也比较广泛,是一种很好的测验和检验水平的方法。
知识点:排序、遍历
分析:简单题,遍历即可
给你一个数字数组 arr 。
如果一个数列中,任意相邻两项的差总等于同一个常数,那么这个数列就称为 等差数列 。
如果可以重新排列数组形成等差数列,请返回 true ;否则,返回 false 。
class Solution {
public:
bool canMakeArithmeticProgression(vector<int>& arr) {
sort(arr.begin(),arr.end());
int d=arr[1]-arr[0];
for(int i=2;i<arr.size();i++)
{
if(arr[i]-arr[i-1]!=d)
return false;
}
return true;
}
};
知识点:遍历、求最值
分析:两只蚂蚁在碰到之后反向走,但实质上只是交换了身份,从全局来看并没有什么影响。找到隔目标端点最远的蚂蚁即可
有一块木板,长度为 n 个 单位 。一些蚂蚁在木板上移动,每只蚂蚁都以 每秒一个单位 的速度移动。其中,一部分蚂蚁向 左 移动,其他蚂蚁向 右 移动。
当两只向 不同 方向移动的蚂蚁在某个点相遇时,它们会同时改变移动方向并继续移动。假设更改方向不会花费任何额外时间。
而当蚂蚁在某一时刻 t 到达木板的一端时,它立即从木板上掉下来。
给你一个整数 n 和两个整数数组 left 以及 right 。两个数组分别标识向左或者向右移动的蚂蚁在 t = 0 时的位置。请你返回最后一只蚂蚁从木板上掉下来的时刻。
class Solution {
public:
int getLastMoment(int n, vector<int>& left, vector<int>& right) {
//脑筋急转弯题,两只蚂蚁在碰到之后反向走,但实质上只是交换了身份,从全局来看并没有什么影响
//所以本题是找隔目标端点最远的蚂蚁
int l=0,r=n;
for(int i=0;i<left.size();i++)
{
l=max(l,left[i]);
}
for(int i=0;i<right.size();i++)
{
r=min(r,right[i]);
}
return max(l,n-r);
}
};
知识点:遍历、枚举
分析:从最后的运行结果来看,虽然这种方法和其他人的动归相比时间复杂度上有一定的差距(但是差距不大,也远没有超时),但是这样写的空间复杂度很低。这种思路每次只计算ij右下角能组成的矩形,是一种思路比较简单的方法
给你一个只包含 0 和 1 的 rows * columns 矩阵 mat ,请你返回有多少个 子矩形 的元素全部都是 1 。
class Solution {
public:
int numSubmat(vector<vector<int> >& mat) {
int res=0;
for (int i = 0; i < mat.size() ; ++i) {
for (int j = 0; j < mat[i].size(); ++j) {
if(mat[i][j]==0) continue;
//每次只计算ij右下角能组成的矩形
int r=mat[0].size();
for (int p = i; p < mat.size(); ++p) {
for (int q = j; q <r ; ++q) { //从ij开始往下找
if (mat[p][q]==0){ //一旦碰到0则更新边界并跳出这层循环
r=q;
break;
}
res++;
}
}
}
}
return res ;
}
};
运行结果:
执行用时:108 ms, 在所有 C++ 提交中击败了52.97%的用户
内存消耗:13.3 MB, 在所有 C++ 提交中击败了100.00%的用户
知识点:递归,字符串处理
分析:本问题主要实现方法是找出字符串中最小的一位数,并通过其位数的次数把它移到最前面,并递归重复此步骤,基本思路已在注释中写出。但这样做时间复杂度比较高,想到复杂度更低的方法了我会及时改进
给你一个字符串 num 和一个整数 k 。其中,num 表示一个很大的整数,字符串中的每个字符依次对应整数上的各个数位 。
你可以交换这个整数相邻数位的数字 最多 k 次。
请你返回你能得到的最小整数,并以字符串形式返回。
class Solution {
public:
string minInteger(string num, int k)
{
//前两个if尽早排除k值太大或者其他特殊情况,以免测试用例设计使代码超时
if (k>num.size()*(num.size()-1)/2)
{
sort(num.begin(),num.end());
return num;
}
if (k<=0) return num;
char Min='9'+1; //Ascll的'9'+1
int t=0; //用于递归
for (int i = 0; i <num.size()&& i<=k ; ++i)
{
if (num[i]<Min)
{
Min=num[i]; //更新最小值
t=i;
if (Min=='0')
{
//开始首位就是0的特殊情况
if (i==0) return '0'+minInteger(num.substr(1),k);
//中间位t有0的情况,要交换t次
return '0'+minInteger(num.substr(0,t)+num.substr(t+1),k-t);
}
}
}
//优先把最小的在t位的数拿到最前面,此过程消耗t步。依此进行递归
return Min+minInteger(num.substr(0,t)+num.substr(t+1),k-t);
}
};