核心内容摘要
Wan2.1-umt5多模态潜力展示:基于文本描述生成简单流程图与架构图
题目解析给定一个整数数组nums要求找出所有不重复的三元组[nums[i], nums[j], nums[k]]满足索引互不相同i ! j、i ! k、j ! k三数之和为 0nums[i] nums[j] nums[k] 0结果中不能包含重复的三元组核心思路这道题的难点在于去重和时间复杂度优化直接暴力枚举的时间复杂度是 \(O(n^
\)会超时。
我们可以用排序 双指针的方法将时间复杂度优化到 \(O(n^
\)。
算法步骤排序预处理先对数组进行排序这样可以利用有序性进行双指针的移动和去重操作。
固定第一个数遍历数组将当前元素作为三元组的第一个数nums[i]。
如果当前数和前一个数相同直接跳过去重。
如果当前数大于 0因为数组是有序的后面的数也都是正数三数之和不可能为 0直接终止循环。
双指针寻找另外两个数用左指针left i 1和右指针right nums.size() - 1来寻找另外两个数计算三数之和sum nums[i] nums[left] nums[right]如果sum 0说明需要更大的数左指针右移如果sum 0说明需要更小的数右指针左移如果sum 0记录该三元组并移动左右指针跳过重复值完整代码cppclass Solution { public: vectorvectorint threeSum(vectorint nums) { vectorvectorint res; int n nums.size(); if (n
return res; // 数组长度不足3直接返回空 sort(nums.begin(), nums.end()); for (int i 0; i n - 2; i) { // 去重跳过与前一个元素相同的情况 if (i 0 nums[i] nums[i-1]) continue; // 剪枝如果当前数已经大于0后面不可能组成和为0的三元组 if (nums[i]
break; int left i 1; int right n - 1; while (left right) { int sum nums[i] nums[left] nums[right]; if (sum
{ left; } else if (sum
{ right--; } else { // 找到一个符合条件的三元组 res.push_back({nums[i], nums[left], nums[right]}); // 跳过左指针重复值 while (left right nums[left] nums[left1]) left; // 跳过右指针重复值 while (left right nums[right] nums[right-1]) right--; // 移动指针继续寻找 left; right--; } } } return res; } };关键优化点排序去重排序后相同的元素会相邻我们可以很方便地跳过重复值。
剪枝操作当固定的第一个数大于 0 时直接终止循环因为后面的数都是正数不可能组成和为 0 的三元组。
双指针移动找到符合条件的三元组后需要同时移动左右指针并跳过重复值避免生成重复的三元组。
复杂度分析时间复杂度\(O(n^
\)其中排序的时间复杂度是 \(O(n \log n)\)双指针遍历的时间复杂度是 \(O(n^
\)。
空间复杂度\(O(\log n)\)排序的栈空间或 \(O(n)\)如果使用了额外的数组存储结果。