有几天没有写力扣了,这几天事情实在有点多。听了几场就业的经验分享,仔细想了一下自己的情况,决定放弃考研,去找个工作了。目标:寒假好好学习->春天找个好点的实习->秋招找个好点的工作。加油吧!
后面刷力扣会多做点题目,每天两个简单题找手感。
1013. 将数组分成和相等的三个部分
这个题目没什么说的,就是几次遍历。第一次算出所有元素和,然后存下来元素和除以3。还是和以前一样,特殊情况直接返回false,这里的特殊情况就是和不能整除3的情况。后面就是遍历,每当当前累加的curSum不等于sum/3时,继续循环。
这里要注意两个常规思维带来的错误,第一个是累加不一定使值增大,即循环退出条件应该是curSum= =sum/3而不是curSum>=sum/3,因为可能先增大后减小从而满足条件。
另一个就是curSum初始值不能为0,因为这样当sum==0时会进不去循环。因此我将curSum设为A[i],即第一个值,然后将i++:
class Solution {
public:
bool canThreePartsEqualSum(vector<int>& A) {
int n=A.size();
int sum=0;
for(int i=0;i<n;i++)
{
sum+=A[i];
}
if(sum%3!=0)
return false;
else {
int i=0;
int flag=0;
while(true)
{
int smallSum=0;
smallSum+=A[i];
i++;
for(;smallSum!=sum/3&&i<n;i++)
{
smallSum+=A[i];
}
if(i>=n)
return false;
if(smallSum==sum/3)
flag++;
if(flag==2)
return true;
}
}
}
};
1053. 交换一次的先前排列
这个题目和 31. 下一个排列 十分相似,都是找字典序列,倒着按递增或递减一次寻找,这是个很好的办法。下面的代码就是这种思想。
swap可以多用,很方便。
注意swap交换的时候要排除相等的情况。
class Solution {
public:
vector<int> prevPermOpt1(vector<int>& A) {
int n=A.size();
int end=n-2;
while(end>=0&&A[end]<=A[end+1])
{
end--;
}
if(end<0)
return A;
int i=end+1;
for(;i<n;i++)
{
if(A[i]>A[end])
break;
}
if(A[end]!=A[i-1] )
swap(A[end],A[i-1]);
else swap(A[end],A[i-2]);
return A;
}
};
- 分割数组为连续子序列
这个题目开始看错了。。。。十分难受。。。
看了题解
感觉题解的贪心算法听巧妙的,后面可以用这种思想来解决连续子串的问题。
class Solution {
public:
bool isPossible(vector<int>& nums) {
unordered_map<int, int> countMap;
unordered_map<int, int> endMap;
for (auto& x : nums) {
int count = countMap[x] + 1;
countMap[x] = count;
}
for (auto& x : nums) {
int count = countMap[x];
if (count > 0) {
int prevEndCount = endMap[x - 1];
if (prevEndCount > 0) {
countMap[x] = count - 1;
endMap[x - 1] = prevEndCount - 1;
endMap[x] = endMap[x] + 1;
} else {
int count1 = countMap[x + 1];
int count2 = countMap[x + 2];
if (count1 > 0 && count2 > 0) {
countMap[x] = count - 1;
countMap[x + 1] = count1 - 1;
countMap[x + 2] = count2 - 1;
endMap[x + 2] = endMap[x + 2] + 1;
} else {
return false;
}
}
}
}
return true;
}
};
代码为力扣题解。