记一次奇怪的做题经历,for循环是用size_t还是int?
引言
题目并不难,是leetcode的238题,因为vscode的默认补齐for循环的临时值类型为size_t,所以一般我也不会去改这个,但是在一次巧合中发现了size_t其实并没有int好用,且看下面分析。
题目描述
给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
输入: [1,2,3,4]
输出: [24,12,8,6]
提示:题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
分析
题目很简单,不再陈述了,下面是我的代码:
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
vector<int> res(nums.size());
res[0] = 1;
for(size_t i = 1; i < nums.size(); i++){
cout << i << endl;
res[i] = res[i-1] * nums[i-1];
}
int right = 1;
for(size_t i = nums.size()-1; i >= 0 ; i--){
res[i] *= right;
right *= nums[i];
}
return res;
}
};
这样一个代码竟然在执行题目的样例的时候出现了段错误,这是为什么呢?没有地方出现问题呀,那么只能打印一下了,
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
vector<int> res(nums.size());
res[0] = 1;
for(int i = 1; i < nums.size(); i++){
cout << i << endl;
res[i] = res[i-1] * nums[i-1];
}
int right = 1;
size_t t = nums.size() - 1;
cout << t << endl;
for(size_t i = nums.size()-1; i >= 0 ; i--){
cout << i << endl;
getchar();
res[i] *= right;
right *= nums[i];
}
return res;
}
};
printf大法好!很清楚,当i为0的之后还会再减1,但是size_t会把-1变为最大的整数,这样的话就陷入死循环了,所以出现了问题。到这里这个令人诧异的问题就水落石出了。
结论
对于我们来说for循环中使用size_t的话会在反向循环的时候陷入死循环,而int就不会出现这样的问题,所以我们需要在进行反向循环的时候注意不要使用size_t,硬要用的话就要改变for的判断条件了。