[C国演义] 第十三章

简介: [C国演义] 第十三章

三数之和

力扣链接

根据题目要求:


返回的数对应的下标各不相同

三个数之和等于0

不可包含重复的三元组 – – 即顺序是不做要求的

如: [-1 0 1] 和 [0, 1, -1] 是同一个三元组

输出答案顺序不做要求

暴力解法: 排序 + 3个for循环 + 去重 — — N^3, 肯定超时

优化: 排序 + 双指针 + 去重 — — N^2

优化的具体思路:

固定一个数, 记作a; 在剩余的空间里面找和为 -a的两个数(由于是排好序的, 所以使用双指针)

去重有两种方法:

1.set去重

2 在循环内部缩小空间 — — 非常值得我们去尝试


set去重

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) 
    {
         // 排序
         sort(nums.begin(), nums.end());
        // 记录结果
        vector<vector<int>> res; 
         // 固定一个数 + 双指针
         int n = nums.size();
         for(int i = 0; i < n; i++) // 固定一个数
         {
             // 双指针优化
             int left = i+1, right = n-1;
             int targt = -nums[i];
             while(left < right)
             {
                 int sum = nums[left] + nums[right];
                 if(sum < targt)
                 {
                     left++;
                 }
                 else if(sum > targt)
                 {
                     right--;
                 }
                 else
                 {
                     res.push_back({nums[i], nums[left], nums[right]});
                     left++;
                     right--;
                 }
             }
         }
        // 去重
         set<vector<int>> result(res.begin(), res.end());
         res.clear();
         for(auto e : result)
         {
             res.push_back(e);
         }
         return res;
    }
};

上面的运行结果太慢了, 我们尝试一下 缩小空间去重👇👇👇

  1. 缩小空间去重
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) 
    {
         // 排序
         sort(nums.begin(), nums.end());
        // 记录结果
        vector<vector<int>> res; 
         // 固定一个数 + 双指针
         int n = nums.size();
         for(int i = 0; i < n;) // 固定一个数
         {
             // 双指针优化
             int left = i+1, right = n-1;
             int targt = -nums[i];
             while(left < right)
             {
                 int sum = nums[left] + nums[right];
                 if(sum < targt)
                 {
                     left++;
                 }
                 else if(sum > targt)
                 {
                     right--;
                 }
                 else
                 {
                     res.push_back({nums[i], nums[left], nums[right]});
                     left++;
                     right--;
                    // 去重left 和 right
                     while(left < right && nums[left] == nums[left-1])  left++;
                     while(right > left && nums[right] == nums[right+1])  right--;
                 }
             }
      // 去重i
             i++;
             while(i < n && nums[i] == nums[i-1])  i++;
         }
         return res;
    }
};

四数之和

力扣链接

这一题就跟上面的题目相似, 思路也很相似: 排序 + 固定两个数, 双指针优化 + 去重. 当然, 我们这里的去重逻辑也是 缩小空间去重

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) 
    {
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        int n = nums.size();
        // 选定一个数, 内部用三数之和
        for(int i = 0; i < n;)
        {
            // 选定一个数, 内部使用双指针优化
            for(int j = i+1; j < n;)
            {
                int left = j+1, right = n-1;
                long int tar = target - (long int)(nums[i]+nums[j]);
                while(left < right)
                {
                    long int cur = nums[left] + nums[right];
                    if(cur < tar)  left++;
                    else if(cur > tar)  right--;
                    else
                    {
                        res.push_back({nums[i], nums[j], nums[left], nums[right]});
                        left++, right--;
                        // 去重left 和 right
                        while(left < right && nums[left] == nums[left-1])  left++;
                        while(right > left && 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 res;
    }
};


相关文章
|
存储 缓存 Java
嵌入式系统中C++内存管理基本方法
嵌入式系统中C++内存管理基本方法
255 0
|
Java
Java Poi-tl操作Word文档,插入文本和图片
poi-tl(poi template language)是Word模板引擎,基于Microsoft Word模板和数据生成新的文档
1890 0
|
缓存 移动开发 安全
Web安全-HTTP响应拆分(CRLF注入)漏洞
Web安全-HTTP响应拆分(CRLF注入)漏洞
782 8
|
存储 分布式计算 数据管理
不可思议!Delta Lake 打造批流一体数据仓库,颠覆传统数据管理的奇迹之作
【9月更文挑战第3天】Delta Lake 是一种高效的数据存储格式,适用于构建批流一体的数据仓库。它支持 ACID 事务,确保数据一致性;能自动处理数据模式变更,简化开发流程。本文将分四步介绍如何使用 Delta Lake 实现批流一体的数据仓库:配置环境、创建 Delta Lake 表、执行批处理与流处理操作。通过示例代码展示其强大功能,适用于电商等多种场景下的数据整合与实时分析。
309 2
|
JavaScript
利用Termux和cpolar在手机上搭建Hexo博客,实现远程访问的完整指南
利用Termux和cpolar在手机上搭建Hexo博客,实现远程访问的完整指南
211 0
|
SQL 分布式计算 NoSQL
快速实践: 通过 Flink CDC 一键整库同步 MongoDB 到 Paimon
Apache Paimon (incubating) 是一项流式数据湖存储技术,可以为用户提供高吞吐、低延迟的数据摄入、流式订阅以及实时查询能力。
77542 4
快速实践: 通过 Flink CDC 一键整库同步 MongoDB 到 Paimon
|
存储 缓存 关系型数据库
第05章 存储引擎【1.MySQL架构篇】【MySQL高级】1
第05章 存储引擎【1.MySQL架构篇】【MySQL高级】1
632 1
|
缓存 Go
一文掌握 Go 文件的写入操作
本文先是对 File.Write、File.WriteString、File.WriteAt 进行介绍,通过例子演示它们的使用方式;然后介绍 File.Seek,说明了它的用法;最后引出 bufio.NewWriter、Writer.WriteString、Writer.Flush,使用它们代替 File 结构体里的写入方法,可以不用频繁操作磁盘,提高写入效率。
488 1
一文掌握 Go 文件的写入操作
|
传感器 数据可视化
【无人机】四轴无人机的轨迹进行可视化和动画处理(Matlab代码实现)
【无人机】四轴无人机的轨迹进行可视化和动画处理(Matlab代码实现)
581 0
|
人工智能 安全 物联网
AI绘画——ChilloutMix模型(现实真人,实现写实逼真的图像)
AI绘画——ChilloutMix模型(现实真人,实现写实逼真的图像)
1424 0