LeetCode求最长公共子数组C++代码报std::out_of_range错误咨询
错误原因分析
- 直接触发越界报错的原因是循环起始下标设置错误:你代码中
l1 = nums1.size() + 1,外层循环i从l1-1 = nums1.size()开始遍历,而vector的合法下标范围是0 ~ nums1.size()-1,调用nums1.at(i)时下标超出范围,直接触发std::out_of_range异常,和你收到的报错信息完全吻合。 - 代码还存在逻辑错误:内层循环中
nums1[i] == nums2[j]后直接加了break,会跳过当前i对应的其余j的判断,完全不符合动态规划的状态转移逻辑。常规的DP定义是dp[i][j]表示以nums1[i]、nums2[j]为起始位置的最长公共子数组长度,当两个位置元素相等时dp[i][j] = dp[i+1][j+1] + 1,不相等时为0,需要遍历所有i和j的组合,不能中途跳出循环。 - 额外隐患:栈上固定开
1000*1000的数组,当输入数组长度超过1000时会出现数组越界,同时栈上分配大内存也容易触发栈溢出。
修复方案
调整循环下标范围,去掉错误的break,改用动态分配的DP数组避免长度限制,修复后的代码如下:
int findLength(vector<int>& nums1, vector<int>& nums2) { int l1 = nums1.size(); int l2 = nums2.size(); // 多开两位空间,避免i+1、j+1越界,默认初始化全0 vector<vector<int>> dp(l1 + 2, vector<int>(l2 + 2, 0)); int maxm = 0; for(int i = l1 - 1; i >= 0; i--){ for(int j = l2 - 1; j >= 0; j--){ if(nums1[i] == nums2[j]){ dp[i][j] = dp[i+1][j+1] + 1; maxm = max(maxm, dp[i][j]); } // 不相等时dp[i][j]保持默认值0,无需额外处理 } } return maxm; }
代码优化点:在状态转移时同步更新最大值,不需要最后再额外遍历一次DP数组,降低时间常数。
内容的提问来源于stack exchange,提问作者Vivek Anand
相关产品推荐
相关产品推荐

