vector<vector<int>>插入问题及threeSum报错解决与内存预分配
问题分析与解决
1. 运行时错误的原因及正确插入方式
你遇到的运行时错误,是因为triplets[total_count]试图访问一个不存在的内层vector——初始时triplets是空的,没有任何元素,直接通过索引访问会触发越界,绑定到空指针。
正确的插入方式有两种:
- 直接构造并插入:利用vector的
push_back或emplace_back直接添加完整的三元组vector,无需维护额外计数变量:if(nums[left_index]+nums[i]+nums[right_index] == 0) { // 直接构造三元组插入外层vector,写法简洁 triplets.push_back({nums[left_index], nums[i], nums[right_index]}); // 用emplace_back可避免临时对象拷贝,效率更高 // triplets.emplace_back(std::initializer_list<int>{nums[left_index], nums[i], nums[right_index]}); } - 分步创建内层vector再插入:如果需要分步添加元素,可先创建临时vector填充后再插入:
if(nums[left_index]+nums[i]+nums[right_index] == 0) { vector<int> triplet; triplet.push_back(nums[left_index]); triplet.push_back(nums[i]); triplet.push_back(nums[right_index]); triplets.push_back(triplet); }
另外注意原代码的一处逻辑漏洞:当total_size<3时,仅写triplets;没有返回,会导致后续代码继续执行,需改成return triplets;。
2. 嵌套vector的内存预分配
可以对嵌套vector进行内存预分配,减少动态扩容带来的性能损耗:
- 外层vector预分配:如果能预估三元组的最大可能数量(比如根据数组大小估算),用
reserve预留空间:vector<vector<int>> triplets; // 按极端情况估算预留空间,可根据实际场景调整 triplets.reserve(total_size * total_size / 6); - 内层vector预分配:由于每个三元组固定是3个int元素,可直接初始化大小或预分配:
直接初始化大小的方式更简洁高效,适合固定长度的场景。// 直接指定大小,无需后续push_back vector<int> triplet(3); triplet[0] = nums[left_index]; triplet[1] = nums[i]; triplet[2] = nums[right_index]; triplets.push_back(triplet); // 或者先预分配再填充 vector<int> triplet; triplet.reserve(3); triplet.push_back(nums[left_index]); triplet.push_back(nums[i]); triplet.push_back(nums[right_index]); triplets.push_back(triplet);
修正后的核心代码片段
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { int total_size=nums.size(); vector<vector<int>> triplets; if(total_size<3) { return triplets; // 补充return,提前返回空结果 } std::sort(nums.begin(),nums.end()); triplets.reserve(total_size * total_size / 6); // 预分配外层空间 for(int i = 1; i<total_size-1;++i) { int right_index = i+1; while(right_index <= total_size-1) { int left_index = 0; // 每轮right循环重置left索引 while(left_index < i) { int sum = nums[left_index]+nums[i]+nums[right_index]; if(sum > 0) { break; } if(sum == 0) { triplets.push_back({nums[left_index], nums[i], nums[right_index]}); } left_index++; } ++right_index; } } return triplets; } };
(注:修正后的代码补充了left_index的重置逻辑,否则right索引递增后,left会停留在上一轮的位置,导致逻辑错误)
内容的提问来源于stack exchange,提问作者Invictus
相关产品推荐
相关产品推荐

