力扣hot6---双指针

news2024/9/25 17:22:15

题目:

TLE做法(哈希+两重for循环)

标签虽然说是用双指针,但是第一个想法真就不是双指针呀。。。就感觉这道题很像:

力扣hot1--哈希-CSDN博客

于是就用了类似的想法:

  1. 首先要排个序,至于为什么要排序,是为了好对三元组集合去重。
  2. 接下来与力扣hot1的想法一样,用哈希来存储一遍这些元素,但是有的元素可能重复了好多次(注意这里数组已经排过序了),所以unordered_map<int,vector<int>>,vector<int>记录对应的索引。
  3. 用双重for循环来判断,第三个数是否在哈希表中,如果存在,还要判断索引是不是一致,如果一致,那就还是不行。如果不一致,那就记录下来,存入res。为了方便去重,这里采用了顺序存取三个数。
  4. 最后用set去重啦,虽然TLE了,但是。。。记录一下代码(以下是TLE的代码

代码:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        //nums排序
        sort(nums.begin(),nums.end());
        //哈希存
        vector<vector<int>> res;
        unordered_map<int,vector<int>> hmap;
        int len=nums.size();
        for(int i=0;i<len;i++){
            hmap[nums[i]].push_back(i);
        }
        //两重for循环遍历
        for(int i=0;i<len-1;i++){
            for(int j=i+1;j<len;j++){
                //cout<<"i:"<<i<<' '<<"j:"<<j<<endl;
                //cout<<"nums_i:"<<nums[i]<<' '<<"nums_j:"<<nums[j]<<endl;
                auto iter=hmap.find(0-nums[i]-nums[j]);
                if(iter!=hmap.end()){
                    auto p=iter->second;
                    int p_len=p.size();
                    for(int k=0;k<p_len;k++){
                        if(p[k]!=i && p[k]!=j){
                            int temp=iter->first;
                            //cout<<"i:"<<nums[i]<<" j:"<<nums[j]<<" temp:"<<temp<<endl;
                            if(temp<=nums[i]){res.push_back({temp,nums[i],nums[j]});}
                            else if(temp>=nums[j]){res.push_back({nums[i],nums[j],temp});}
                            else{res.push_back({nums[i],temp,nums[j]});}
                            break;
                        }
                    }
                }
            }
        }
        //set去重
        set<vector<int>> q(res.begin(),res.end());
        res.assign(q.begin(),q.end());

        return res;
    }
};

这里记录一下set去重:

//set去重
set<vector<int>> q(res.begin(),res.end());
res.assign(q.begin(),q.end());

C++ 给vector去重的三种方法_c++ vector去重-CSDN博客

单循环+双指针做法

言归正传,双指针思路:

  1. 首先,先给数组排个序。为什么要排序呢,有点像二分的思想。这里可以先大致感受一下,L 指针在最左面,R 指针在最右面,满足三个数之和等于0,那就添加结果。小于0就说明 L 指针指的数有点小了,往右侧移动。大于0就说明 R 指针指的数有点大了,往左侧移动。
  2. 排完序后,依次遍历数组中的每个元素,就代表三个元素之和已经降维成了两个元素之和,或许可以想到哈希表的做法(为什么双指针也很方便呢?因为这道题不是返回索引,可以进行排序),后面将尝试哈希表的做法~
  3. 如果说遍历到的元素索引为 i ,那么 L = i +1,R = nums.size( ) - 1。然后进行第一段的说法,也就是:
while(L<len && R>=0 && L<R){
    if(nums[i]+nums[L]+nums[R]==0){
        res.push_back({nums[i],nums[L],nums[R]});
        while(L<R && nums[L+1]==nums[L] && L+1<len){L++;}
        while(L<R && nums[R-1]==nums[R] && R-1>=0){R--;}
            L++;R--;
    }
    else if(nums[i]+nums[L]+nums[R]<0){L++;}
    else{R--;}
}

代码如下:

C++:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        
        sort(nums.begin(),nums.end());
        
        vector<vector<int>> res;
        int len=nums.size();
        for(int i=0;i<len;i++){
            if(nums[i]>0){break;}
            if(i>0 && nums[i]==nums[i-1]){continue;}
            int L=i+1;
            int R=len-1;
            while(L<R){
                if(nums[i]+nums[L]+nums[R]==0){
                    res.push_back({nums[i],nums[L],nums[R]});
                    while(L<R && nums[L]==nums[L+1]){L++;}
                    while(L<R && nums[R]==nums[R-1]){R--;}
                    L++;
                    R--;
                }
                else if(nums[i]+nums[L]+nums[R]<0){L++;}
                else{R--;}
            }
        }
        return res;
    }
};

Python:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res=[]
        nums.sort()
        len_nums=len(nums)
        for i in range(len_nums):
            if nums[i]>0:
                break
            if i>0 and nums[i]==nums[i-1]:
                continue
            L=i+1
            R=len_nums-1
            while L<R:
                if nums[i]+nums[L]+nums[R]==0:
                    res.append([nums[i],nums[L],nums[R]])
                    while L<R and nums[L]==nums[L+1]:
                        L+=1
                    while L<R and nums[R]==nums[R-1]:
                        R-=1
                    L+=1
                    R-=1
                elif nums[i]+nums[L]+nums[R]<0:
                    L+=1
                else:
                    R-=1
        return res
        

单循环+哈希做法

哈希思路:

数组遍历循环每一个元素,对于该元素,在该元素的右侧进行【两数之和=0-该元素】的降维处理。可参考:力扣hot1--哈希-CSDN博客

代码如下:

C++:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        
        sort(nums.begin(),nums.end());
        
        int len=nums.size();
        vector<vector<int>> res;
        for(int i=0;i<len-2;i++){
            if(nums[i]>0){break;}
            if(i>0 && nums[i]==nums[i-1]){continue;}
            unordered_map<int,int> hmap;
            int target=-nums[i];
            int temp_last=0x3f3f3f3f;
            for(int j=i+1;j<len;j++){
                int temp=target-nums[j];
                if(hmap.find(temp)!=hmap.end()){
                    res.push_back({nums[i],nums[j],temp});
                }
                else{
                    hmap[nums[j]]=1;
                }
            }
        }
        set<vector<int>> s(res.begin(),res.end());
        res.assign(s.begin(),s.end());
        return res;
    }
};

Python:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        len_nums=len(nums)

        res=[]

        for i in range(len_nums-2):
            if nums[i]>0:
                break
            if i>0 and nums[i]==nums[i-1]:
                continue
            hmap={}
            target=-nums[i]
            temp_last=0x3f3f3f3f
            for j in range(i+1,len_nums):
                temp=target-nums[j]
                if temp in hmap:
                    res.append([nums[i],nums[j],temp])
                else:
                    hmap[nums[j]]=1
        s=set(tuple(x) for x in res)
        res=[list(x) for x in s]
        return res

Python中的去重:

s=set(tuple(x) for x in res)
res=[list(x) for x in s]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1486605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 如何从 Binlog 找出变更记录并回滚

文章目录 前言1. 案例模拟1.1 确认信息1.2 下载 Binlog1.3 准备环境1.4 注册 Binlog1.5 准备结构信息1.6 Python 订阅1.7 输出结果展示 2. 原理解析2.1 程序设计2.2 模块版本 总结 前言 最近有研发同学问我&#xff1a;有一个问题&#xff0c;想查一个 ID 为 xxxx 的 sku 什么…

Linux(CentOS为例)环境下 Git提交代码加速,使用FastGithub,运行报错解决

当你的在服务器上使用Git进行推送时&#xff0c;时常会出现超时错误。这里使用FastGithub 首先下载FastGithub 这个软件作者不是为什么删除了GithUb的仓库&#xff0c;这个链接还有。下载Linux版本的 FastGithub Linux&#xff0c;Windows版本 下载完毕后解压 ./fastgithu…

Linux课程四课---Linux开发环境的使用(gcc/g++编译器的相关)

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

[VSCode插件] 轻量级静态博客 - MDBlog

MDBlog VSCode插件&#xff0c;基于Markdown的轻量级静态博客系统&#xff0c;同时支持导出为可以部署的静态博客。 仓库 MDBlog 1. Features 博客基础功能&#xff1a;分类管理、文章管理、自动生成索引快捷指令&#xff1a;快捷输入表格、mermaid、wavedrom、代码块发布&a…

Photoshop 2023:重塑创意,引领数字艺术新纪元

在数字艺术的浩瀚星空中&#xff0c;Adobe Photoshop 2023&#xff08;简称PS 2023&#xff09;如同一颗璀璨的新星&#xff0c;为Mac和Windows用户带来了前所未有的创意体验。这款强大的图像处理软件不仅继承了前作的精髓&#xff0c;更在细节上进行了诸多创新&#xff0c;让每…

前端el-date-picker传递的日期格式不是自己想要的格式

解决方法&#xff1a; 添加format和value-format属性进行解决。 format“YYYY-MM-DD” value-format“YYYY-MM-DD” 注意&#xff1a;日期格式要用大写&#xff01;&#xff01;&#xff01;&#xff01;用小写会出现错误&#xff0c;不能回填选择的日期&#xff0c;会直接传入…

【 buuctf-swp】

wget 是什么东西呢&#xff1f; 那就直接过滤 http 流&#xff0c;并全部导出&#xff0c;点击 save all在导出来的一大堆里发现个 zip&#xff0c;需要输入密码&#xff0c;macOS 一大特点就是&#xff0c;如果是伪加密&#xff0c;随便输入一个密码就可以解压缩&#xff0c;…

Redis7 实现持久化的三种方式

1、概述 1.1、Redis持久化的重要性 数据恢复&#xff1a;Redis是一个内存数据库&#xff0c;如果系统或服务宕机&#xff0c;内存中的数据将会丢失。Redis的持久化机制可以把数据保存到磁盘上&#xff0c;以便在系统重启后恢复数据。这是Redis持久化最基本也是最重要的功能。…

基于阿里云OSS上传图片实战案例

一、案例描述 基于Springboot框架实现一个上传图片到阿里云服务端保存的小案例。 二、准备工作 基于Springboot免费搭载轻量级阿里云OSS数据存储库&#xff08;将本地文本、照片、视频、音频等上传云服务保存&#xff09;-CSDN博客 三、代码 新建这两个类&#xff1a;一个…

MySQL:开始深入其数据(四)select子查询

select眼熟吧?(都三节了) 又开始学习了 在 MySQL 中&#xff0c;子查询&#xff08;subquery&#xff09;是指在一个查询内嵌套另一个完整的 SELECT 语句。子查询可以嵌套在 SELECT、INSERT、UPDATE、DELETE 语句中&#xff0c;用于从内部查询结果中获取数据&#xff0c;进而完…

新加坡大带宽服务器概览

随着全球互联网的迅猛发展&#xff0c;服务器作为支撑网络应用的重要基础设施&#xff0c;扮演着越来越重要的角色。新加坡&#xff0c;作为亚洲四小龙之一&#xff0c;其服务器市场也备受关注。特别是新加坡的大带宽服务器&#xff0c;更是受到了众多企业和个人的青睐。那么&a…

LeetCode -- 79.单词搜索

1. 问题描述 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水…

SNAP:如何批量预处理Sentinel2 L2A数据集并输出为TIFF文件?

我的需求 我目前就是希望下载哨兵2号数据&#xff0c;然后在SNAP中进行批量提取真彩色波段并输出为TIFF文件。 数据集下载说明 目前哨兵网站似乎进行了一大波更新&#xff0c;连网站都换了&#xff0c;网址如下&#xff1a; https://dataspace.copernicus.eu/ 打开后界面如…

Linux课程四课---Linux开发环境的使用(自动化构建工具-make/Makefile的相关)

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

C++进阶(三) 二叉搜索树

一、二叉搜索树 1.1 二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节…

【论文】A Survey of Monte Carlo Tree Search Methods阅读笔记

本文主要是将有关蒙特卡洛树搜索的文献&#xff08;2011年之前&#xff09;进行归纳&#xff0c;概述了核心算法的推导&#xff0c;给出了已经提出的许多变化和改进的一些结构&#xff0c;并总结了MCTS方法已经应用于的博弈和其他领域的结果。 蒙特卡洛树搜索是一种通过在决策…

Java 石头剪刀布小游戏

一、任务 编写一个剪刀石头布游戏的程序。程序启动后会随机生成1~3的随机数&#xff0c;分别代表剪刀、石头和布&#xff0c;玩家通过键盘输入剪刀、石头和布与电脑进行5轮的游戏&#xff0c;赢的次数多的一方为赢家。若五局皆为平局&#xff0c;则最终结果判为平局。 二、实…

深入理解与应用工厂方法模式

文章目录 一、模式概述**二、适用场景****三、模式原理与实现****四、采用工厂方法模式的原因****五、优缺点分析****六、与抽象工厂模式的比较**总结 一、模式概述 ​ 工厂方法模式是一种经典的设计模式&#xff0c;它遵循面向对象的设计原则&#xff0c;特别是“开闭原则”&…

一文扫盲:室内导航系统的应用场景和技术实现(入门级)

hello&#xff0c;我是贝格前端工场&#xff0c;之间搞过一些室内导航项目&#xff0c;有2D也有3D的&#xff0c;算是有些经验&#xff0c;这里给大家分享一下室内导航的基本尝试&#xff0c;欢迎老铁们点赞、关注&#xff0c;如有需求可以私信我们。 一、室内导航是什么 室内…

vs报错1168链接错误——关于:LNK1168 无法打开 E:\VS\文件名\x64\Debug\文件名. 进行写入问题的解决方法

关于这个问题我在网上找了一些方法。 有些方法解决了这个问题&#xff0c; 但是有点麻烦&#xff0c; 有些方法可能不能解决问题。 这里我先把我在网上找到的方法写出来&#xff1a; 第一种方法是可能开着一个程序&#xff0c;就是这个终端。有的时候报错1168是因为你没有关这…