2024.7.12 刷题总结
2024.7.12
**每日一题**
2974.最小数字游戏,这道题是一个简单模拟题,我们只需要根据题意完成即可,题目的意思是每次从数组中选出最小的两个元素,然后先放入第二小的,再放最小的,所以我们只需要先对数组排序,然后再依次取出两个元素放进去即可。
457.环形数组是否存在循环,这道题是一个考察快慢指针的题目,将数组中的n个点看作图中的n个节点,再将i+nums[i]看作每个节点延伸出去的单向边,所以现在题目变成判断有无环路的题目,这时我们就可以遍历数组,初始化快慢指针,快指针在慢指针前面一步,然后每次快指针走两步,慢指针走一步,直到他们相遇。我用的并不是这种方法,而是通过一直根据规则往前遍历来寻找,其实是一个暴力做法,但是可以根据题目条件进行剪枝,首先题目说了满足条件的数组元素要么全正要么全负,那么我们可以标记第一个元素的正负,如果后面出现符号不同的元素就直接退出。还需要标记一个已经走的步数,最后判断答案时,步数需要大于1才是有效的答案,并且在走的过程中,需要设置步数大于一定值自动退出,否则会出现runtime error.
class Solution {public :
bool circularArrayLoop(vector<int> & nums) {
bool flag = false;
int n = nums.size();
if (n == 1) return false;
int f = 0;
int cnt = 0;
int len = 0;
for (int i = 0; i < n; i++) {
if (nums[i] > 0) f = 1;
else f = 0;
len = 0;
if (f == 1) {
cnt = (i + nums[i]) % n;
len++;
while (cnt != i) {
if (nums[cnt] < 0) break;
if(len>1000) break;
else{
cnt = (cnt + nums[cnt]) % n;
len++;
}
}
if (cnt == i && len > 1) flag = true;
}
else {
if (i + nums[i] >= 0) cnt = (i + nums[i])%n;
else {
int a=i+nums[i];
while (a<0){
a+=n;
}
cnt=a%n;
}
len++;
while (cnt != i) {
if (nums[cnt] > 0) break;
if(len>1000) break;
else {
if (cnt + nums[cnt] >= 0) cnt =
(cnt + nums[cnt])%n;
else {
int c = cnt + nums[cnt];
while(c<0) c+=n;
cnt = c%n;
len++;
}
}
}
if (cnt == i && len > 1) flag = true;
}
}return flag;
}
};
42.接雨水,这道题是一个经典的动态规划问题,根据题意可以有很多种解题方法,可以按行也可以按列来求解,这里我们选用的是按列来求解。
每一列能接到的雨水取决于左右两侧的高度最大值的更小值和自身的高度,所以我们从前往后和从后往前遍历两次数组,分别处理出每列的左边最大值和右边最大值。然后我们再遍历数组加上答案即可。注意最大值数组需要初始化第一个和最后一个,更新最大值公式应该是用前一个值来更新,因为当前还没有数值。
原文地址:https://blog.csdn.net/TheJustice_/article/details/140372473
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!