1、两数之和,有序时,双指针,最左最右求和比较,nums[left]+nums[right]<sum,说明最左边太小了,加上最右边都<sum,剩下的所有数据都无法满足+nums[left]的情况,left++,对于right同样,时间复杂度为O(n),空间复杂度O(1)
167.两数之和 || - 输入有序数组
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int len = numbers.size();
int left = 0;
int right = len - 1;
while (left < right) {
if (numbers[left] + numbers[right] < target) {
left++;
} else if (numbers[left] + numbers[right] > target) {
right--;
} else {
return {left + 1, right + 1};
}
}
return {0, 0};
}
};
两数之和无序时,还可以使用哈希,map[nums[i]],find(map[sum-nums[i]]),找到即是满足的,时间复杂度:O(n),空间复杂度O(n)
1.两数之和
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> hashMap;
for (int i = 0; i < nums.size(); i++) {
auto it = hashMap.find(target - nums[i]);
if (it != hashMap.end()) {
return {it->second, i};
}
hashMap[nums[i]] = i;
}
return {};
}
};
2、如何衡量一个算法的时间复杂度优化,获取了多少信息量来衡量一个算法的效率;
3、利用更多的信息
4、数据无序时,可以先排序
5、三数之和,先排序,固定第一个数i,j,k为相向双指针,从两端遍历
15.三数之和
// 第一个数固定不动,后面两个数相向双指针
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(), nums.end());
int size = nums.size();
for (int i = 0; i < size - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue; // 跳过相同三元组
if (nums[i] + nums[i+1] + nums[i+2] > 0) break; // 最小的三个元素相加都大于0,后面所有都不满足
if (nums[i] + nums[size-2] + nums[size-1] < 0) continue; // i与最大的两个元素相加都小于0,说明i太小了,跳过
int j = i + 1;
int k = size - 1;
while (j < k) {
int sum = nums[i] + nums[j] + nums[k];
if (sum > 0) {
k--;
} else if (sum < 0) {
j++;
} else {
res.push_back({nums[i], nums[j], nums[k]});
j++;
while (j < k && nums[j] == nums[j - 1]) { // 跳过相同三元组
j++;
}
k--;
while (j < k && nums[k + 1] == nums[k]) { // 跳过相同三元组
k--;
}
}
}
}
return res;
}
};