当前位置: 首页> 财经> 股票 > 龙江人社使用教程_展示型企业网站例子_百度指数怎么看_seo关键词选择及优化

龙江人社使用教程_展示型企业网站例子_百度指数怎么看_seo关键词选择及优化

时间:2025/8/8 3:19:10来源:https://blog.csdn.net/2401_87255690/article/details/147527575 浏览次数:0次
龙江人社使用教程_展示型企业网站例子_百度指数怎么看_seo关键词选择及优化

四数之和

  • 一、题目链接
  • 二、题目
  • 三、题目解析
  • 四、算法原理
    • 解法一:排序 + 暴力枚举 + 利用 set 去重
    • 解法二:排序 + 双指针
  • 五、编写代码
  • 六、时间复杂度和空间复杂度

一、题目链接

四数之和

二、题目

在这里插入图片描述

三、题目解析

题目要求基本与三数之和一样。

四、算法原理

解法几乎照搬三数之和

解法一:排序 + 暴力枚举 + 利用 set 去重

绝对超时,时间复杂度是O(n^4)。

解法二:排序 + 双指针

示例1排好序:

在这里插入图片描述

步骤:

  1. 排序
  2. 从左向右依次固定一个数a
  3. 在a的右区间内,利用"三数之和"找到三个数,使这三个数之和等于target - a即可:从左向右依次固定一个数b,在b的右区间内利用"双指针"找到两个数,使这两个数之和等于target - a - b即可。

代码大体样子:两层for循环,中间套了一个双指针算法。不过这只是大体样子,还需要解决和"三数之和"同样的细节问题:结果不重且不漏。

不重:"三数之和"仅有两个地方。因为这里多了一个数,所以有3个地方要保证不重

  • 找到一个四元组结果,left和right都要跳过重复元素
  • 每使用完一遍"双指针",b也跳过重复元素
  • b每遍历完一遍,a也跳过重复元素

不漏:"双指针"找到一结果就缩小区间。

五、编写代码

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;// 1.排序sort(nums.begin(), nums.end());// 2.固定数a,固定数b,双指针算法int n = nums.size();for (int i = 0; i < n; )// 固定数a{// 三数之和for (int j = i + 1; j < n; )// 固定数b{// 双指针int aim = target - nums[i] - nums[j];int left = j + 1, right = n - 1;while (left < right){int sum = nums[left] + nums[right];if (sum > aim) --right;else if (sum < aim) ++left;else{// 找到一结果就push_back,保证不漏缩小区间ret.push_back({ nums[i], nums[j], nums[left++], nums[right--]});// 去重 left和rightwhile (left < right && nums[left] == nums[left - 1]) ++left;while (left < right && nums[right] == nums[right + 1]) --right;}}// 去重j++j;while (j < n && nums[j] == nums[j - 1]) ++j;}// 去重i++i;while (i < n && nums[i] == nums[i - 1]) ++i;}return ret;}
};

数据范围溢出的风险,计算的时候可能会超出int的范围:

在这里插入图片描述

可以用long long类型的变量存储,后面的计算过程只用对第一个数据/第二个数据强制转换:

long long aim = (long long)target - nums[i] - nums[j];
long long aim = target - (long long)nums[i] - nums[j];

完整代码:

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;// 1.排序sort(nums.begin(), nums.end());// 2.固定数a,固定数b,双指针算法int n = nums.size();for (int i = 0; i < n; )// 固定数a{// 三数之和for (int j = i + 1; j < n; )// 固定数b{// 双指针long long aim = target - (long long)nums[i] - nums[j];if (nums[i] > 0 && nums[j] > 0 && target < 0) break; int left = j + 1, right = n - 1;while (left < right){int sum = nums[left] + nums[right];if (sum > aim) --right;else if (sum < aim) ++left;else{// 找到一结果就push_back,保证不漏缩小区间ret.push_back({ nums[i], nums[j], nums[left++], nums[right--]});// 去重 left和rightwhile (left < right && nums[left] == nums[left - 1]) ++left;while (left < right && nums[right] == nums[right + 1]) --right;}}// 去重j++j;while (j < n && nums[j] == nums[j - 1]) ++j;}// 去重i++i;while (i < n && nums[i] == nums[i - 1]) ++i;}return ret;}
};

六、时间复杂度和空间复杂度

for循环嵌套for循环嵌套while循环,所以时间复杂度是O(n^3)

空间复杂度依旧是排序算法占空间,所以空间复杂度是O(logn)

关键字:龙江人社使用教程_展示型企业网站例子_百度指数怎么看_seo关键词选择及优化

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: