T1 (leetcode 6027)
比赛时的错误代码
(114 / 119 个通过测试用例)
class Solution {
public:
int countHillValley(vector<int>& nums) {
int sum = 0;
for(int i = 1; i < nums.size() - 1; i ++){
if(nums[i] > nums[i - 1] && nums[i] > nums[i + 1]){
sum ++;
}
else if(nums[i] < nums[i - 1] && nums[i] < nums[i + 1]){
sum ++;
}
else if(nums[i] == nums[i + 1]){
int j = i + 1;
while(nums[i] == nums[j + 1]){
j ++;
}
if(nums[i] > nums[i - 1] && nums[j] > nums[j + 1]){
sum ++;
}
else if(nums[i] < nums[i - 1] && nums[j] < nums[j + 1]){
sum ++;
}
}
}
return sum;
}
};
思路真的很混乱,其实由这混乱的思路中可以提取出两种有用的思路
首先就是因为有重复的数,所以我们不能直接一个个遍历判断,这里我就进行了特判(搞了一大堆,还有些细节问题导致没过),其实只需要去重就可以了啊。。
1、代码如下
class Solution {
public:
int countHillValley(vector<int>& t) {
int sum = 0;
vector<int> nums;
nums.emplace_back(t[0]);
for(int i = 1; i < t.size(); i ++){
if(t[i] != t[i - 1]){
nums.emplace_back(t[i]);
}
}
for(int i = 1; i < nums.size() - 1; i ++){
if(nums[i] > nums[i - 1] && nums[i] > nums[i + 1]){
sum ++;
}
else if(nums[i] < nums[i - 1] && nums[i] < nums[i + 1]){
sum ++;
}
}
return sum;
}
};
还有就是第二种思路,只需要找到相同元素的首尾,再比较即可,其中 pan 记录第一个不同元素的起始位置,这里就将所有的变为了一般情况
2、代码如下
class Solution {
public:
int countHillValley(vector<int>& nums) {
int sum = 0;
int pan = 1;
for(int i = 1; i < nums.size(); i ++){
if(nums[i] == nums[pan]){
continue;
}
if(nums[pan - 1] < nums[i - 1] && nums[i - 1] > nums[i]){
sum ++;
}
if(nums[pan - 1] > nums[i - 1] && nums[i - 1] < nums[i]){
sum ++;
}
pan = i;
}
return sum;
}
};
T2 (leetcode 6028)
这题我有好多细节没有去考虑,真的需要你静下心来去模拟一下
这道题和括号匹配那题有相似之处,同样用栈模拟
我弄了好久,对题目的分析能力和细节处理能力真的太差了,
代码如下
class Solution {
public:
int countCollisions(string xx) {
stack<char> aa;
int ans = 0;
for(int i = 0; i < xx.size(); i ++){
if(xx[i] == 'R'){
aa.push(xx[i]);
}
else if(xx[i] == 'S'){
while(!aa.empty() && aa.top() == 'R'){
ans ++;
aa.pop();
}
aa.push('S');
}
else{
int fu = 0;
if(!aa.empty() && aa.top() == 'S'){
ans ++;
}
while(!aa.empty() && aa.top() == 'R'){
if(fu == 0){
ans += 2;
}else{
ans ++;
}
aa.pop();
fu = 1;
}
if(fu == 1){
aa.push('S');
}
}
}
return ans;
}
};
还有就是大佬的脑筋急转弯了,现阶段不太可能想到,题目练的实在太少了
此解法参考 newchar,只有两种情况会撞车:
1、左边的车往右开,右边的车往左开,此时撞车后对答案的贡献为2,其实每辆车对答案的贡献都为1
2、左边的车往右开碰到静止的车,右边的车往左开碰到静止的车,此时撞车后每辆车对答案的贡献也为1
也就是说,在左右两个端点:左边往左开和右边往右开的车永远也不会有交集,我们只需要判断中间车辆的情况,对于中间的车辆,只要不是静止状态,那么一定会撞车(可能相撞也可能遇到静止的车),对答案的贡献都是1,所以枚举时候计算即可。
class Solution {
public:
int countCollisions(string xx) {
int l = 0, r = xx.size() - 1;
int ans = 0;
while(l <= r && xx[l] == 'L'){
l ++;
}
while(l <= r && xx[r] == 'R'){
r --;
}
for(int i = l; i <= r; i++){
if(xx[i] != 'S'){
ans ++;
}
}
return ans;
}
};
总之就是遇到题的思路很混乱,题目还是练少了,需要将往届的周赛题目刷一下
还有就是刷题的质量真的有待提高,不仅需要过,还要弄清楚为什么会这样想,分析方式,还有没有其他的解法,有时候还是太懒了