力扣大厂热门面试算法题 15-17

        15. 三数之和,16. 最接近的三数之和,17. 电话号码的字母组合,每题做详细思路梳理,配套Python&Java双语代码, 2024.03.11 可通过leetcode所有测试用例。

目录

15. 三数之和

解题思路

完整代码

Java

Python

​编辑

16. 最接近的三数之和

解题思路

完整代码

Java

Python

17. 电话号码的字母组合

解题思路

完整代码

Java

Python


15. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != 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] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
 

解题思路

        为了找到所有和为0且不重复的三元组,我们可以使用双指针法。这个方法涉及到先对数组进行排序,然后遍历数组,对于每个元素,使用两个指针分别指向元素之后的开始位置和数组的末尾,向中间移动两个指针来找到和为0的三元组。这里有几个关键点需要注意:

  1. 排序:先对数组进行排序,这样可以方便地跳过重复的元素。
  2. 遍历:从数组的开始遍历到倒数第三个元素(因为我们需要的是三元组)。
  3. 双指针:对于每个遍历到的元素,将一个指针指向遍历元素的下一个位置,另一个指针指向数组的末尾。根据这两个指针指向的元素之和与当前遍历到的元素之和来移动指针。
  4. 跳过重复元素:在遍历过程中,如果遇到重复的元素,需要跳过,以避免重复的三元组。

完整代码

Java
public class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);  // 排序
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0; i < nums.length - 2; i++) {  // 遍历到倒数第三个元素
            if (i > 0 && nums[i] == nums[i - 1]) {  // 跳过重复元素
                continue;
            }
            int l = i + 1, r = nums.length - 1;
            while (l < r) {
                int sum = nums[i] + nums[l] + nums[r];
                if (sum < 0) {
                    l++;
                } else if (sum > 0) {
                    r--;
                } else {
                    res.add(Arrays.asList(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--;
                }
            }
        }
        return res;
    }
}
Python
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()  # 排序
        result = []
        for i in range(len(nums)-2):  # 遍历到倒数第三个元素
            if i > 0 and nums[i] == nums[i-1]:  # 跳过重复元素
                continue
            l, r = i+1, len(nums)-1  # 双指针
            while l < r:
                s = nums[i] + nums[l] + nums[r]
                if s < 0:
                    l += 1
                elif s > 0:
                    r -= 1
                else:
                    result.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
        return result

16. 最接近的三数之和

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解。

示例 1:

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
示例 2:

输入:nums = [0,0,0], target = 1
输出:0
 

提示:

3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000

解题思路

        为了找到和与目标值 target 最接近的三个整数的和,我们可以使用一种类似于解决“三数之和”问题的方法,即使用双指针法。基本思路如下:

  1. 排序:首先,对数组 nums 进行排序,这有助于使用双指针法。

  2. 初始化最接近的和:用一个变量记录当前找到的与 target 最接近的和,初始时可以设为第一个元素、第二个元素和最后一个元素的和,或者设置为一个较大的数。

  3. 遍历:遍历数组,对于每个元素 nums[i],使用两个指针分别指向 i 之后的元素和数组的最后一个元素。基于当前三元组的和与 target 的差距,移动指针。

  4. 移动双指针:如果三元组的和大于 target,为了使和更接近 target,应该减小和,因此将右指针左移。如果三元组的和小于 target,为了使和更接近 target,应该增加和,因此将左指针右移。

  5. 更新最接近的和:在每一步中,如果找到了更接近 target 的和,则更新记录的最接近的和。

  6. 返回结果:遍历结束后,记录的最接近的和即为所求。

完整代码

Java
public class Solution {
    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int closestSum = nums[0] + nums[1] + nums[nums.length - 1];  // 初始化最接近的和
        for (int i = 0; i < nums.length - 2; i++) {
            int l = i + 1, r = nums.length - 1;
            while (l < r) {
                int currentSum = nums[i] + nums[l] + nums[r];
                if (currentSum == target) {  // 如果等于target,直接返回
                    return currentSum;
                }
                
                // 更新最接近的和
                if (Math.abs(currentSum - target) < Math.abs(closestSum - target)) {
                    closestSum = currentSum;
                }
                
                // 根据和与target的比较,移动双指针
                if (currentSum < target) {
                    l++;
                } else {
                    r--;
                }
            }
        }
        return closestSum;
    }
}
Python
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        closest_sum = sum(nums[:3])  # 初始化最接近的和
        for i in range(len(nums) - 2):
            l, r = i + 1, len(nums) - 1
            while l < r:
                current_sum = nums[i] + nums[l] + nums[r]
                if current_sum == target:  # 如果等于target,直接返回
                    return current_sum
                
                # 更新最接近的和
                if abs(current_sum - target) < abs(closest_sum - target):
                    closest_sum = current_sum
                    
                # 根据和与target的比较,移动双指针
                if current_sum < target:
                    l += 1
                else:
                    r -= 1
        return closest_sum

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

示例 2:

输入:digits = ""
输出:[]

示例 3:

输入:digits = "2"
输出:["a","b","c"]

提示:

  • 0 <= digits.length <= 4
  • digits[i] 是范围 ['2', '9'] 的一个数字。

解题思路

        可以使用回溯法。回溯法是一种通过探索所有可能的候选解来找出所有的解的算法。如果候选解被确认不是一个解(或者至少不是最后一个解),回溯算法会通过在上一步进行一些变化来丢弃该解,即回溯并尝试另一个可能的解。

        具体到这个问题,可以将每个数字对应到其可以代表的所有字母,然后通过回溯遍历这些字母的所有可能组合。

  1. 创建一个映射表,将每个数字映射到相应的字母。
  2. 创建一个函数来实现回溯机制,该函数将接受当前组合的字符串和接下来处理的数字字符串。
  3. 从输入字符串的第一个数字开始,将其映射到对应的所有字母,并对每个字母,添加到当前的组合字符串中,并进行下一轮回溯,即再处理下一个数字。
  4. 如果数字字符串为空,表示所有的数字都已处理完毕,此时的组合字符串为一个完整的解,将其添加到答案列表中。
  5. 重复步骤3和4,直到遍历完所有的数字,找出所有可能的字母组合。

完整代码

Java
public class Solution {
    public List<String> letterCombinations(String digits) {
        List<String> combinations = new ArrayList<>();
        if (digits == null || digits.length() == 0) {
            return combinations;
        }
        
        String[] phoneMap = {
            "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"
        };

        backtrack(combinations, phoneMap, digits, 0, new StringBuilder());
        return combinations;
    }

    public void backtrack(List<String> combinations, String[] phoneMap, String digits, int index, StringBuilder path) {
        if (index == digits.length()) {
            combinations.add(path.toString());
            return;
        }
        
        String possibleLetters = phoneMap[digits.charAt(index) - '0'];
        for (char letter : possibleLetters.toCharArray()) {
            path.append(letter);
            backtrack(combinations, phoneMap, digits, index + 1, path);
            path.deleteCharAt(path.length() - 1); // 回溯
        }
    }
}
Python
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if not digits:
            return []

        phoneMap = {
            "2": "abc", "3": "def", "4": "ghi", "5": "jkl",
            "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"
        }

        def backtrack(index, path):
            # 如果路径长度与输入数字长度相同,将其添加到结果中
            if len(path) == len(digits):
                combinations.append("".join(path))
                return
            
            # 获取当前数字对应的所有可能的字母
            possible_letters = phoneMap[digits[index]]
            for letter in possible_letters:
                # 添加当前字母到路径中,并进入下一层回溯
                path.append(letter)
                backtrack(index + 1, path)
                path.pop()  # 回溯,移除路径最后一个字母

        combinations = []
        backtrack(0, [])
        return combinations

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

29.基于SSM实现的少儿编程网上报名系统(项目 + 论文PPT)

项目介绍 随着计算机的不断发展&#xff0c;已经融入到我们生活工作的每一个领域中&#xff0c;给我们的生活工作带来了很多的便利&#xff0c;因此&#xff0c;希望可以通过该系统的开发也能使少儿编程网上报名系统实现信息化管理&#xff0c;减轻人的负担&#xff0c;提高工作…

申请选择商家转账到零钱流程怎样的

商家转账到零钱是什么&#xff1f; 【商家转账到零钱】可以说是【企业付款到零钱】的升级版&#xff0c;商家转账到零钱可以为商户提供同时向多个用户微信零钱转账的能力&#xff0c;支持分销返佣、佣金报酬、企业报销、企业补贴、服务款项、采购货款等自动向用户转账的场景。…

伦敦金交易市场的参与者有哪些?

伦敦金交易市场&#xff0c;作为全球最大的黄金交易市场之一&#xff0c;吸引了众多的参与者。这些参与者来自不同的背景和角色&#xff0c;每个人都在这个市场中发挥着重要的作用。 首先&#xff0c;我们不得不提到的是市场的核心参与者——交易商。交易商是市场上最活跃的群体…

FTP,SFTP,FTPS,SSL,TSL简介,区别,联系,使用场景说明

文章目录 简介FTPFTPSSFTP加密场景选择FTPS还是SFTPFTP、SFTP、FTPS区别、联系和具体使用场景如何使用FTP、SFTP和FTPSSSLTLSSSL和TLS区别和联系&#xff0c;以及使用场景SSL和TLS技术上的区别一些问题隐式的TLS&#xff08;FTPS/SSL&#xff09;或者显式的TLS&#xff08;FTPS…

【Python】新手入门学习:什么是python解释器,它的作用是什么?

【Python】新手入门学习&#xff1a;什么是python解释器&#xff0c;它的作用是什么&#xff1f; &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基…

STM32CubeMX学习笔记19——SD卡(SDIO接口)

1、简介 1.1 SD卡简介 很多单片机系统都需要大容量存储设备&#xff0c;以存储数据&#xff08;常用的有U盘、FLASH芯片、SD卡等&#xff09;&#xff0c;比较而言SD卡是单片机大容量外部存储的首选&#xff0c;只需要少数几个IO口即可外扩一个容量从几十M到几十G的&#xff…

前端实现 查询包含分页 以及封装table表格 上手即用!

表格组件是 element plus 中的table 又经过了一层封装 封装的table代码在最底下 <div class"box2"><el-radio-group v-model"radio" style"margin-bottom: 16px"><el-radio-button label"1">类型1</el-radio…

vue3 uniapp 项目初始化集成配置【开箱即用】

https://gitee.com/charrie/vue3-uniapp-init 技术说明 采用vue3viteuniapp技术栈&#xff0c;setup语法糖编码方式引入unocss量子化样式引擎&#xff0c;动态css不用自己写样式&#xff0c;引用class即可&#xff0c;降低代码体积全局请求入口已封装&#xff0c;使用时自己封…

易基因: WGBS+ChIP-seq揭示食管癌的细胞类型和癌症特异性表观遗传调控|Genome Biol

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 食管癌是一种常见的恶性肿瘤&#xff0c;有两种亚型&#xff1a;鳞状细胞癌&#xff08;squamous cell carcinoma&#xff0c;ESCC&#xff09;和腺癌&#xff08;adenocarcinoma&#x…

【C++】string类(介绍、常用接口)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;http://t.csdnimg.cn/eCa5z 目录 string类的常用接口说明 string类对象的常见构造 ​编辑 string字符串的遍历&#xff08;迭代器&#xf…

力扣刷题Days12--104二叉树最大深度(js)

目录 1&#xff0c;题目 2&#xff0c;代码 2.1深度优先遍历--递归思想 2.2-0广度优先搜索--错误版 2.2广度优先搜索 3&#xff0c;学习与总结 3.1二叉树的复习 3.2array常用函数复习 1&#xff0c;题目 给定一个二叉树 root &#xff0c;返回其最大深度。二叉树的 最大…

解决Iterm2升级后遇到“Stashed changes“的问题

&#xff1c;&#xff1c;&#xff1c;&#xff1c;&#xff1c;&#xff1c;&#xff1c; Updated upstream ...... &#xff1e;&#xff1e;&#xff1e;&#xff1e;&#xff1e;&#xff1e;&#xff1e; Stashed changes冲突标记符的代码如题&#xff0c;最近有升级Item2…

鸿蒙原生应用元服务开发-WebGL网页图形库开发接口说明

一、场景介绍 WebGL主要帮助开发者在前端开发中完成图形图像的相关处理&#xff0c;比如绘制彩色图形等。目前该功能仅支持使用兼容JS的类Web开发范式开发。 二、接口说明 表1 WebGL主要接口列表 本文参考引用HarmonyOS官方开发文档&#xff0c;基于API9。

RStudio更换R语言版本

今天下载R语言用于读取.xlsx文件的readxl包时&#xff0c;RStudio提示该包是使用R-4.3.3版本构建&#xff0c;而我现在使用的是R-4.3.2版本&#xff0c;所以需要升级一下R语言版本&#xff0c;这里先下载最新版本的R语言&#xff0c; 下载地址&#xff1a;The Comprehensive R…

Early if-conversion - 优化阅读笔记

Early if-conversion 用于对于没有很多可预测指令的乱序CPU。目标是消除可能误预测的条件分支。 来自分支两侧的指令都会被推测性地执行&#xff0c;并使用 cmov 指令选择结果。 // SSAIfConv 类在确定可能的情况下&#xff0c;对SSA形式的机器码执行if-conversion。该类不包…

基于JAVA实现自由教学平台设计【附项目源码】分享

基于JAVA实现自由教学平台系统演示 视频&#xff1a;ssm自由教学平台演示录像-CSDN直播基于JAVA实现自由教学平台设计https://live.csdn.net/v/369811 项目源码地址&#xff1a;https://download.csdn.net/download/weixin_43894652/88842681 一、目标 构建一个基于JAVA的网…

第八十天 WAF攻防-漏洞利用HPP污染分块传输垃圾数据

第80天 WAF攻防-漏洞利用&HPP污染&分块传输&垃圾数据 参考点&#xff1a; #将MySQL注入函数分为几类 拆分字符串函数&#xff1a;mid、1eft、1pad等 编码函数&#xff1a;ord、hex、a3ci等 运算函数&#xff1a;*/&^&#xff01;1 ike rlike reg等 空格替换部…

Python-Pong-Game

我还加了音效&#xff0c;类似于小时候游戏机上的弹球游戏 import os import turtle import pygame#初始化pygame pygame.init()#加载声音文件 bounce_sound pygame.mixer.Sound("bounce.mp3")wn turtle.Screen() wn.title("Pong by ") wn.bgcolor(&qu…

【猫头虎科技解码】探秘Drools语法:规则引擎在实战中的应用️

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

关于yolov8文档的记录,补充一些整理的知识点

2023年由Ultralytics 提供了YOLOv8开源项目。YOLOv8 支持全方位的视觉 AI 任务&#xff0c;包括检测、分割、姿态估计、跟踪和分类。这种多功能性使用户能够在各种应用和领域中利用YOLOv8 的功能。安装yolov8开源项目 pip install githttps://github.com/ultralytics/ultralyti…