记一次奇怪的做题经历,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的判断条件了。
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号