实习冲刺第二十九天

15.三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

**注意:**答案中不可以包含重复的三元组。

示例 1:

复制代码
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

思路详解:

  1. 首先使用sort对数组进行排序

  2. 遍历排序后的数组,固定好一个元素nums[i],将left指针初始化为i+1,将right指针初始化为数组末尾。

  3. 当left < right时,

  • 计算三个元素的和sum = nums[i] + nums[left] + nums[right]。

  • 如果sum等于零,将这个三元组[nums[i], nums[left], nums[right]]添加到结果集中。

  • 如果sum小于零,说明需要增大和,将left指针右移一位。

  • 如果sum大于零,说明需要减小和,将right指针左移一位。

  • 注意,如果出现重复的元素,需要跳过,以避免重复的三元组。

  1. 继续遍历数组,直到遍历完所有的元素。

代码详解:

cpp 复制代码
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n = nums.size();
        sort(nums.begin(), nums.end()); // 对数组进行排序,以便后续操作
        vector<vector<int>> answer; // 存储结果
          for (int i = 0; i < n - 2; i++) { //遍历数组,固定第一个元素
            // 避免重复的固定元素
            if (i > 0 && nums[i] == nums[i - 1])
                continue;
            int left = i + 1; // 左指针指向固定元素的下一位
            int right = n - 1; // 右指针指向数组末尾
            while (left < right) {//保证两个指针不相遇,相遇说明所有情况以及遍历
                int sum = nums[i] + nums[left] + nums[right]; // 计算三个元素的和
                if (sum < 0) { // 如果和小于零,说明需要增大和,左指针右移一位
                    left++;
                }
                else if (sum > 0) { // 如果和大于零,说明需要减小和,右指针左移一位
                    right--;
                }
                else { // 和等于零,找到满足条件的三元组
                    answer.push_back({nums[i], nums[left], nums[right]}); // 将三元组添加到结果中
                    //如果左指针的下一个元素和本身相同说明我们以及考虑过这个数字,则跳过
                    while (left < right && nums[left] == nums[left + 1])
                        left++;
                    //右指针同理
                    while (left < right && nums[right] == nums[right - 1])
                        right--;
                    //当我们判断完一个三元组后让指针移动指向新的元素,这样可以避免产生相同的三元组
                    left++; 
                    right--; 
                }
            }
        }  
        return answer;
    }
};

面经

  1. 什么是c++中的模板特化和偏特化,如何实现他们
  • 模板特化是指为特定的数据类型提供一个专门的模板定义。当我们希望对于某些特定的类型,模板有不同的实现时,可以使用模板特化。
cpp 复制代码
template <>
void swap<int>(int& a, int& b) {
    // 更高效的位操作交换
    if (a != b) {
        a ^= b;
        b ^= a;
        a ^= b;
    }
}//这里的template <>表示这是一个特化,而void swap<int>(int& a, int& b)表示这是针对int类型的特化实现。
  • 偏特化是指对模板参数进行更具体的限制,而不是完全指定一个特定的类型。偏特化可以应用于类模板和函数模板,但通常更多地用于类模板。
cpp 复制代码
template <typename T, typename Allocator>
class Storage {
    // ...
};

template <typename T>
class Storage<T, allocator<T>> {
    // 针对allocator<T>的优化实现
    // ...
};
//在这个例子中,我们没有为T提供一个特定的类型,而是为Allocator参数提供了一个特定的类型allocator<T>,这就是偏特化的一个例子。
相关推荐
虾饺爱下棋11 分钟前
FCN语义分割算法原理与实战
人工智能·python·神经网络·算法
云手机掌柜1 小时前
从0到500账号管理:亚矩阵云手机多开组队与虚拟定位实战指南
数据结构·线性代数·网络安全·容器·智能手机·矩阵·云计算
Eloudy4 小时前
简明量子态密度矩阵理论知识点总结
算法·量子力学
点云SLAM4 小时前
Eigen 中矩阵的拼接(Concatenation)与 分块(Block Access)操作使用详解和示例演示
人工智能·线性代数·算法·矩阵·eigen数学工具库·矩阵分块操作·矩阵拼接操作
没书读了4 小时前
考研复习-数据结构-第八章-排序
数据结构
算法_小学生5 小时前
支持向量机(SVM)完整解析:原理 + 推导 + 核方法 + 实战
算法·机器学习·支持向量机
waveee1235 小时前
学习嵌入式的第三十四天-数据结构-(2025.7.29)数据库
数据结构·数据库·学习
iamlujingtao6 小时前
js多边形算法:获取多边形中心点,且必定在多边形内部
javascript·算法
算法_小学生6 小时前
逻辑回归(Logistic Regression)详解:从原理到实战一站式掌握
算法·机器学习·逻辑回归
DebugKitty6 小时前
C语言14-指针4-二维数组传参、指针数组传参、viod*指针
c语言·开发语言·算法·指针传参·void指针·数组指针传参