算法01_较小的三数之和
题目
给定一个长度为 n 的整数数组和一个目标值 target,寻找能够使条件
nums[i] + nums[j] + nums[k] < target 成立的三元组 i, j, k
个数(0 <= i < j < k < n)。
思路:排序 + 二分查找和排序 + 对撞指针等三种方法
1.暴力求解
三个for循环
时间复杂度:O(n^3),其中 n 是数组的长度。
空间复杂度:O(1),未开辟额外存储空间。
int threeSumSmaller(int* nums, int numsSize, int target){
int cnt = 0;
for (int i = 0; i < numsSize - 2; ++i) {
for (int j = i + 1; j < numsSize - 1; ++j) {
for (int k = j + 1; k < numsSize; ++k) {
if (nums[i] + nums[j] + nums[k] < target) {
cnt++;
}
}
}
}
return cnt;
}
2.排序 + 二分查找
时间复杂度:O(n^2lgn),其中 n 是数组的长度。
空间复杂度:O(1),未开辟额外存储空间。
int threeSumSmaller(vector<int>& nums, int target) {
int cnt = 0;
int size = nums.size();
sort(nums.begin(), nums.end());
for (int i = 0; i < size - 2; ++i) {
for (int j = i + 1; j < size - 1; ++j) {
int sum = target - nums[i] - nums[j];
int left = j + 1, right = size - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] >= sum) {
right = mid - 1;
} else {
left = mid + 1;
}
}
cnt += (right - j);
}
}
return cnt;
}
3.排序 + 对撞指针
时间复杂度:O(n^2),其中 n 是数组的长度。
空间复杂度:O(1),未开辟额外存储空间。
int threeSumSmaller(vector<int>& nums, int target) {
int cnt = 0;
int size = nums.size();
sort(nums.begin(), nums.end());
for (int i = 0; i < size - 2; ++i) {
int sum = target - nums[i];
int left = i + 1, right = size - 1;
while (left < right) {
if (nums[left] + nums[right] < sum) {
cnt += (right - left);
left++;
} else {
right--;
}
}
}
return cnt;
}
浙公网安备 33010602011771号