常写算法,多动脑,不会老!
3Sum问题:
若不考虑效率问题,则解决该问题的思路就很简单直接,三个 for 循环遍历穷举即可。一个优秀的程序员肯定不能忍受这么无脑的时间复杂度,于是先想到先对全部数据进行排序操作,然后设置三个指针,数组的首尾各一,第三个指针从首位+1开始。设置合理的条件限制,移动指针。该过程中需要解决去重问题。
废话不多说,贴代码:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> resultVector;
sort(nums.begin(),nums.end());// 排序
for (int i = 0; i < nums.size(); i ++) {
if (nums[i] > 0) break;
if (i > 0 && nums[i] == nums[i-1]) continue; // 始终保持num[i]没出现过(达到去重的目的)
int begin = i + 1, end = (int)nums.size() - 1;
while (begin < end) {
int sum3 = nums[i] + nums[begin] + nums[end];
if (sum3 < 0) {
while (begin < end && nums[begin] == nums[begin+1]) {
begin ++; // 去重
}
begin ++;
} else if (sum3 > 0) {
while (begin < end && nums[end] == nums[end-1]) {
end --; // 去重
}
end --;
} else {
resultVector.push_back({nums[i],nums[begin],nums[end]});
while (begin < end && nums[begin] == nums[begin+1]) {
begin ++; // 去重
}
while (begin < end && nums[end] == nums[end-1]) {
end --; // 去重
}
begin ++;
end --;
}
}
}
return resultVector;
}
上述代码思路很清晰,效率也较高。
再来看看非常类似的 3Sum Closest 问题:
3Sum Closest问题:
该问题相对于 3Sum 问题来说更加灵活,其目标值不再是0,而是任意给定的数值,通过加和三个数使得结果最接近给定值。但是思想是相似的,且也有简约的地方,如并不需考虑去重的情况。
代码示例:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end()); // 先做排序操作
int minDiff = INT_MAX;
int closestSum = target;
for (int i = 0; i < nums.size(); i ++) {
int begin = i + 1, end = (int)nums.size() - 1;
while (begin < end) {
int sum3 = nums[i] + nums[begin] + nums[end];
int currentDiff = abs(sum3 - target);
if (currentDiff < minDiff) {
closestSum = sum3;
minDiff = currentDiff;
} else if (sum3 < target) {
begin ++;
} else if (sum3 > target) {
end --;
} else {
return closestSum;
}
}
}
return closestSum;
}