【力扣刷题 | 第五天】

news2024/11/26 21:53:46

目录

前言:

15. 三数之和 - 力扣(LeetCode)

18. 四数之和 - 力扣(LeetCode)

结束:


前言:

今天两道题类型相似,解法思路一致,都利用了双指针技术。



15. 三数之和 - 力扣(LeetCode)

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

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

解法1:哈希表法:

我们仍然可以建立一个map表来存储a+b的值以及a和b的值,再次遍历整个数组,如果利用find函数能找到一个c等于(-(a+b)),那么我们就往数组中存储这三个数字,但是这种方法对于去重来讲太过于复杂因此我们不推荐使用这种方法。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());
        // 找出a + b + c = 0
        // a = nums[i], b = nums[j], c = -(a + b)
        for (int i = 0; i < nums.size(); i++) {
            // 排序之后如果第一个元素已经大于零,那么不可能凑成三元组
            if (nums[i] > 0) {
                break;
            }
            if (i > 0 && nums[i] == nums[i - 1]) { //三元组元素a去重
                continue;
            }
            unordered_set<int> set;
            for (int j = i + 1; j < nums.size(); j++) {
                if (j > i + 2
                        && nums[j] == nums[j-1]
                        && nums[j-1] == nums[j-2]) { // 三元组元素b去重
                    continue;
                }
                int c = 0 - (nums[i] + nums[j]);
                if (set.find(c) != set.end()) {
                    result.push_back({nums[i], nums[j], c});
                    set.erase(c);// 三元组元素c去重
                } else {
                    set.insert(nums[j]);
                }
            }
        }
        return result;
    }
};

解法2:双指针法

我们可以先对数组进行排序,然后以此遍历这个数组,每一次遍历的时候建立两个指针:left指针和right指针,left指针指向遍历数组的后一位元素,right指针指向末尾元素:

 此时我们固定住遍历指针,对left指针和right指针进行以下操作:
   1.计算nums[遍历指针]+nums[left]+nums[right]的和。

        2.如果三者的和大于零,因为已经进行了排序,我们就移动right指针,使和减小。

        3.如果三者的和小于零,就移动left指针,使和增大。

如此操作之下,我们最终无非得到两个结果

1.得到了两个left和right指针指向的值使得其加上遍历指针指向的值为0,则为我们要寻找的答案。

2.无法找到left和right指针能使其值加上遍历指针指向值后的结果为0,则该值没有答案。

去重操作:
因为我们在之前已经进行过排序,因此重复的数字一定是在一起的。如果遇到了重复的数字,我们就让指针向后指,直到指针指向的值与指针+1指向的值不相等(因为相同的数字会放在一起,所以如果nums[i]!=nums[i+1],那么nums[i]在数组中肯定没有重复元素)。

对遍历指针去重:

 if (i > 0 && nums[i] == nums[i - 1])
  {
          continue;
  }

对left和right指针去重:

while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;

完整代码:

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

18. 四数之和 - 力扣(LeetCode)

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。

双指针解法:
与上一题思路解法一致,只不过又多了一个外层循环,也就是说我们这次要固定两个遍历指针

class Solution {
public:
  vector<vector<int>> fourSum(vector<int>& nums, int target) {
  sort(nums.begin(),nums.end());
  vector<vector<int>> result;
  for(int k=0;k<nums.size();k++)

 {   if(nums[k]>target && nums[k]>0&&target>0)
     {
       continue;
     }   
     if (k > 0 && nums[k] == nums[k - 1])
     {
       continue;
     }
     for(int i=k+1;i<nums.size();i++)
      {
        if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) 
          {
             break;
          }
        // 对nums[i]去重
        if (i > k + 1 && nums[i] == nums[i - 1]) 
        {
          continue;
         }
       int left=i+1;
       int right=nums.size()-1;
       int sums=0;
                
      while(left<right)
       {
                   
         if((long)nums[k]+nums[i]+nums[left]+nums[right]>target)
         {
           right--;
         }
         else if((long)nums[k]+nums[i]+nums[left]+nums[right]<target)
         {
          left++;
         }
         else if((long)nums[k]+nums[i]+nums[left]+nums[right]==target)
         {
                               
           result.push_back(vector<int{nums[i],nums[left],nums[right],nums[k]);
         
                      
           while (right > left && nums[right] == nums[right - 1]) right--;
           while (right > left && nums[left] == nums[left + 1]) left++;
                       
                       right--;
                       left++;
          }
      }
       }
       

            
 }
          return result;

  }
};

结束:

今天的内容到这里就结束了,感谢大家的阅读。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

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

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

相关文章

PostgreSQL数据库分区裁剪——enable_partition_pruning

在PostgreSQL 10版本之前&#xff0c;PostgreSQL数据库实际上是没有单独的创建分区表的DDL语句&#xff0c;都是通过表继承的原理来创建分区表&#xff0c;这样使得在PostgreSQL中使用分区表不是很方便&#xff0c;到PostgreSQL 10之后&#xff0c;PostgreSQL扩展了创建表的DDL…

idea插件开发-PSI

程序结构接口&#xff08;Program Structure Interface&#xff09;简称PSI&#xff0c;PSI是IDEA插件开发最复杂的一块内容&#xff0c;后续会有大量实战来强化理解此处的知识。PSI是IntelliJ 平台中的一个层&#xff0c;负责解析文件并创建语法和语义代码模型&#xff0c;为平…

Linux 导入MySQL数据库(四)

文章目录 一、导出数据库二、导入数据库&#xff08;方法一&#xff09;1. 通过FinalShell连接服务器&#xff0c;登录mysql&#xff1a;2. 新建数据库3. 使用新建的数据库4. 对数据库进行编码设置5. 从路径中导入 SQL 文件数据 三、导入数据库&#xff08;方法二&#xff09;【…

为uni-cloud(Dcloud国产之辉)声明!

目录 uni-cloud的介绍 uni-cloud与uni-app的关系 uni-cloud与云原生的关系 uni-cloud的开发优点 uni-cloud与HBuilder X结合的优越性 uni-cloud高效解决"高并发" uni-cloud与阿里云、腾讯云完美结合 uni-cloud背后庞大的插件市场 美中不足 加油&#xff01…

chatgpt赋能python:Python代码保存:如何保存你的Python代码?

Python代码保存&#xff1a;如何保存你的Python代码&#xff1f; Python被广泛认为是学习编程的入门语言之一&#xff0c;因为它易于学习和使用&#xff0c;并且拥有大量的库和框架来处理各种任务。 在编写Python代码时&#xff0c;你可能会像大多数编程任务一样&#xff0c;…

实践项目三: 校园兼职平台(合作重构版)

项目说明 1 据了解&#xff0c;目前在校大学生80%以上有做兼职的需求&#xff0c;兼职打工已经不仅仅是经济困难的学生赚取生活费用的途径。调查显示&#xff0c;全球经济危机对就业产生冲击&#xff0c;用人单位对人员的社会实践能力要求提高&#xff0c;大学期间必要的社会实…

Java学习笔记(StringJoiner和集合)

StringJoiner StringJoiner与StringBuilder一样&#xff0c;也可以看成是一个容器&#xff0c;创建之后的内容是可变的 作用&#xff1a;提高字符串的操作效率&#xff0c;而且代码编写特别简洁&#xff0c;但是目前市场上很少有人用 构造方法&#xff1a; 方法名 说明 pub…

四、HAL_驱动机械按键

1、开发环境。 (1)KeilMDK&#xff1a;V5.38.0.0 (2)STM32CubeMX&#xff1a;V6.8.1 (3)MCU&#xff1a;STM32F407ZGT6 2、机械按键简介 (1)按键内部是机械结构&#xff0c;也就是内部是没有电路的。按键按下内部引脚导通&#xff0c;松开内部断开。 3、实验目的&原理…

Git、Github、Gitee的区别

⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;Git 目录 1、Git2、Gitee3、GitHub 什么是版本管理&#xff1f;   版本管理是管理各个不同的版本&#xff0c;出了问题可以及时回滚。 1、Git Git是一个分布式版本控制系统&#xff0c;用于跟踪和管理代码的变化。它是…

开源代码分享(2)—综合能源系统零碳优化调度

参考文献&#xff1a; Optimal dispatch of zero-carbon-emission micro Energy Internet integrated with non-supplementary fired compressed air energy storage system | SGEPRI Journals & Magazine | IEEE Xplore 1.引言 全球能源危机和环境污染的双重压力促使能量…

mysql 删表引出的问题

背景 将测试环境的表同步到另外一个数据库服务器中&#xff0c;但有些表里面数据巨大&#xff0c;&#xff08;其实不同步该表的数据就行&#xff0c;当时没想太多&#xff09;&#xff0c;几千万的数据&#xff01;&#xff01; 步骤 1. 既然已经把数据同步过来的话&#x…

chatgpt赋能python:Python怎么从1加到100

Python怎么从1加到100 Python是一种面向对象的编程语言&#xff0c;随着人工智能和大数据技术的流行&#xff0c;Python也变得越来越受欢迎。Python有很多优点&#xff0c;其中之一就是易于学习和使用。在这篇文章中&#xff0c;我们将介绍如何用Python从1加到100。 前置知识…

还在为浏览量焦虑吗?为何不用R语言来做归因分析找出痛点

一、引言 大家好&#xff0c;我是一名博客作者&#xff0c;同时也是一个有着浏览量焦虑症的患者。每次发一篇新的博客文章&#xff0c;我总是不停地刷新页面&#xff0c;看看有多少人来访问、阅读和留言。当发现访问量不如自己预期时&#xff0c;我就会有一种被冷落、被忽视的…

【DFT】MBIST (1) MBIST基础

MBSIT基础 1. 存储器测试2. 存储器结构3. 存储器故障模型3.1 固定故障(SAF)3.2 转换故障(TF)3.3 耦合故障(CF)3.4 桥接和状态耦合故障 4. 功能测试方法4.1 March 测试算法4.2 March-C 算法4.3 MATS 算法4.4 其他的 March 测试 5. MBSIT方法5.1 简单的 March MBIST1. 简单的Marc…

灵动超值系列FTHR-G0140开发板

文章目录 引言MM32G0140微控制器FTHR-G0140电路板MM32G0140最小核心系统供电系统可编程按键和小灯扩展插座 MindSDK软件开发平台 引言 2023年上半年的一些活动现场&#xff08;包括但不限于4月在苏州的全国高校电子信息类专业教学论坛、5月和6月在同济大学、四川大学、南京大学…

Vue3+Vite+TypeScript常用项目模块详解

目录 1.Vue3ViteTypeScript 概述 1.1 vue3 1.1.1 Vue3 概述 1.1.2 vue3的现状与发展趋势 1.2 Vite 1.2.1 现实问题 1.2 搭建vite项目 1.3 TypeScript 1.3.1 TypeScript 定义 1.3.2 TypeScript 基本数据类型 1.3.3 TypeScript语法简单介绍 2. 项目配置简单概述 2.…

chatgpt赋能python:如何在Python中二次运行同一个命令语句

如何在Python中二次运行同一个命令语句 如果您是一个熟练的Python开发者&#xff0c;一定会遇到必须二次运行同一个命令语句的情况。在本文中&#xff0c;我们将探讨Python中的几种方法来实现这一目标。 方法1&#xff1a;使用Python Shell Python Shell是Python解释器的一个…

R 语言学习笔记

1. 基础语法 赋值 a 10; b <- 10;# 表示流向&#xff0c;数据流向变量&#xff0c;也可以写成10 -> b创建不规则向量 不用纠结什么是向量&#xff0c;就当作一个容器&#xff0c;数据类型要相同 a c("我","爱","沛")创建一定规则的向…

编译原理 | 课程设计 — 语法分析

第1关&#xff1a;使用C/C语言编写PL/0编译程序的语法分析程序 1、任务描述 基于第二章的词法分析程序&#xff0c;使用C/C语言编写PL/0编译程序的语法分析程序。 2、编程要求 完成上述编程任务&#xff0c;将C/C语言源程序复制粘贴到右侧代码编辑器&#xff0c;点击“评测”按…

bthclsbthclsbthcls

Sql简单查询 创建数据库/表 进入数据库&#xff1a;mysql -uroot -p123456 支持中文字符&#xff1a; Set character_set_databaseutf8; Set character_set_serverutf8; 1.创建数据库 create database demo; use demo; 2.创建数据表 create table score( id int primar…