C++算法练习-day18——15.三数之和

题目来源:. - 力扣(LeetCode)

题目思路分析

题目描述 :

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有独特三元组,并返回所有独特三元组的列表。注意:答案中不可以包含重复的三元组。

解题思路:

  1. 排序:首先对数组进行排序,这样可以方便后续的查找和去重。
  2. 固定一个数:遍历数组,固定一个数 numsi,然后使用双指针法查找另外两个数 numsj 和 numsk,使得 numsi + numsj + numsk = 0。
  3. 双指针法 :
    • 初始化两个指针,左指针 j = i + 1,右指针 k = n - 1。
    • 计算三数之和,根据和的大小调整指针位置:
      • 如果和小于 0,则左指针右移,增加和的值。
      • 如果和大于 0,则右指针左移,减少和的值。
      • 如果和等于 0,则找到了一个解,将结果添加到答案中,并移动指针以避免重复解。
  4. 去重:在遍历过程中,如果当前元素与前一个元素相同,则跳过,以避免重复解。

代码:

cpp 复制代码
#include <vector>  
#include <algorithm>  
  
class Solution {  
public:  
    std::vector<std::vector<int>> threeSum(std::vector<int>& nums) {  
        std::vector<std::vector<int>> ans;  
        int n = nums.size();  
          
        // 对数组进行排序  
        std::sort(nums.begin(), nums.end());  
          
        // 遍历数组,固定一个数  
        for (int i = 0; i < n - 2; ++i) {  
            // 去重:如果当前元素与前一个元素相同,则跳过  
            if (i > 0 && nums[i] == nums[i - 1]) {  
                continue;  
            }  
              
            // 初始化右指针  
            int k = n - 1;  
              
            // 使用双指针法查找另外两个数  
            for (int j = i + 1; j < n - 1; ++j) {  
                // 去重:如果当前元素与前一个元素相同,则跳过  
                if (j > i + 1 && nums[j] == nums[j - 1]) {  
                    continue;  
                }  
                  
                // 调整右指针位置,直到找到满足条件的三数之和  
                while (j < k && nums[i] + nums[j] + nums[k] > 0) {  
                    --k;  
                }  
                  
                // 如果左指针与右指针相遇,则结束内层循环  
                if (j == k) {  
                    break;  
                }  
                  
                // 如果找到满足条件的三数之和,则添加到答案中  
                if (nums[i] + nums[j] + nums[k] == 0) {  
                    ans.push_back({nums[i], nums[j], nums[k]});  
                }  
            }  
        }  
          
        return ans;  
    }  
};

知识点摘要

  1. 排序算法:使用排序算法(如快速排序、归并排序)对数组进行排序,以便后续操作。
  2. 双指针法:在有序数组中使用双指针法查找满足条件的元素,可以提高查找效率。
  3. 去重处理:在遍历过程中,通过比较当前元素与前一个元素是否相同,来避免重复解。

本题通过排序和双指针法,有效地解决了在数组中找到所有独特三元组的问题,使得三数之和为零。排序使得数组有序,从而可以使用双指针法进行高效的查找。同时,通过去重处理,避免了重复解的出现。这种解题思路不仅适用于本题,还可以扩展到其他类似的查找问题中,如四数之和、五数之和等。通过排序和双指针法的结合,可以大大提高查找效率,减少时间复杂度。

相关推荐
云和数据.ChenGuang1 小时前
Python 常见特殊方法详解:__new__、__init__、__del__、__str__、__repr__ 与 __getattribute__
开发语言·人工智能·python·1024程序员节
海宇服务1 小时前
零信任架构实战:基于海宇全国车辆配置查验构建自动化二手商用车出厂参数建档网关
运维·人工智能·架构·自动化·1024程序员节
xyouyuweizhu1 小时前
字节流与字符流:Java IO 的两条主线该怎么选
java·开发语言·python
小超人诞生日记2 小时前
C++ 异常机制详解:从抛出捕获到异常安全
c++·算法
多弗朗皮卡丘2 小时前
C++的IO流
开发语言·c++·io流·文件io流
骑着蜗牛撵大象3272 小时前
AI Agent 工程化开发实战(三):用 StateGraph 给智能体搭一条可回放的状态流水线
java·开发语言·jvm·ai·状态管理·langgraph·stategraph
zhippt_10143 小时前
AI生成PPT工具推荐:图转PPT与一键生成实测对比
人工智能·1024程序员节
itmigrate3 小时前
Rust 里的所有权误区:不是不写 clone 就叫高性能
开发语言·后端·rust
Brilliantwxx3 小时前
【Linux】 文件访问与路径解析:目录、文件名、dentry、路径缓冲与 dcache 全解析
linux·运维·服务器·开发语言·spring
鬼手点金3 小时前
KV Cache 未必是一次性的:可编辑、可组合的“笔记”
java·人工智能·笔记·学习·自动化·1024程序员节