LeetCode#377的C ++ DP解决方案,此代码是否有错误?

时间:2019-12-24 17:44:07

标签: c++ c++11

此C ++解决方案是讨论论坛中top voted Java solution的直接翻译。我自己的G ++编译器可以在此测试用例中正常编译和运行,但是LeetCode提交会产生错误(请快速尝试)。

我认为内存已正确初始化,并且边界检查已经到位。可能是什么问题?

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        vector<int> dp(target + 1, 0);
        dp[0] = 1;
        for (int i = 1; i < dp.size(); i++) {
            for (int j = 0; j < nums.size(); j++) {
                if (i - nums[j] >= 0) {
                    dp[i] += dp[i - nums[j]];
                }
            }
        }
        return dp[target];
    }
};

int main(int argc, char** argv) {
    vector<int> nums {
        3, 33, 333,
    };
    cout << Solution().combinationSum4(nums, 10000) << endl;
    return 0;
}

测试用例:

[3,33,333]
10000

错误消息:

Line 9: Char 17: runtime error: signed integer overflow: 357856184 + 1941940377 cannot be represented in type 'int' (solution.cpp)

2 个答案:

答案 0 :(得分:2)

该消息清楚地显示了错误。 357856184 + 1941940377 = 2299796561,大于32位int max-> 2 ^ 31-1 = 2147483647。

在C ++标准中,不能保证int的大小。为了安全起见,根据C ++ 11,可以使用int64_t。

https://en.cppreference.com/w/cpp/language/types

答案 1 :(得分:0)

此算法正确但存在缺陷。它在计算过程中不处理整数溢出。改进的解决方案如下:

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        vector<long> dp(target + 1, 0);
        dp[0] = 1;
        for (int i = 1; i < dp.size(); i++) {
            for (int j = 0; j < nums.size(); j++) {
                if (i - nums[j] >= 0) {
                    dp[i] += dp[i - nums[j]];
                    dp[i] %= numeric_limits<int>::max();
                }
            }
        }
        return dp[target];
    }
};