leetcode题17电话号码的字母组合-java题解-回溯篇

news2024/12/29 10:47:21

说明:问题描述来源leetcode:

一、问题描述:

17. 电话号码的字母组合

难度中等2219

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

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

img

示例 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'] 的一个数字。

通过次数609,617

提交次数1,052,457

二、题解:

题解1:

没剪枝

public class Solution {
    List<String> result = new LinkedList<>();
    LinkedList<Character> path = new LinkedList<>();
    String digits;
    HashMap<Character, String> map = new HashMap<>();
    public Solution() {
        map.put('2',"abc");
        map.put('3',"def");
        map.put('4',"ghi");
        map.put('5',"jkl");
        map.put('6',"mno");
        map.put('7',"pqrs");
        map.put('8',"tuv");
        map.put('9',"wxyz");
    }

    public List<String> letterCombinations(String digits) {
        this.digits = digits;
        if (digits.length() == 0) return result;
        backTracking(0);
        return result;
    }

    private void backTracking(int startIndex) {
        if (path.size() == digits.length()) result.add(getPathStr());

        for (int i = startIndex; i < digits.length(); i++) {
            char c = digits.charAt(i);
            for (char ch : map.get(c).toCharArray()) {
                path.add(ch);
                backTracking(i + 1);
                path.removeLast();
            }
        }

    }

    private String getPathStr() {
        StringBuilder stringBuilder = new StringBuilder();
        for (char c : path) {
            stringBuilder.append(c);
        }
        return stringBuilder.toString();
    }    
}

上面是没剪枝的,到底是怎么没剪枝呢?分析下,递归的最初那一层当遍历到digit第二个元素时,也就是最终的结果了,再进入递归是永远都不能满足path.size() == digits.length(),因此我们要剔除这些无用的递归操作,此时的path.size()肯定是小于startIndex的,这两者都不同步了。因此可以以startIndex != path.size()作为判断当前走入的递归是否是无意义的。

换一种处理数据的方法,并且进行剪枝:

class Solution {
    String[] strings = new String[8];
    List<String> result = new LinkedList<>();
    LinkedList<Character> path = new LinkedList<>();
    String digits;
    public Solution() {
        strings[0] = "abc";
        strings[1] = "def";
        strings[2] = "ghi";
        strings[3] = "jkl";
        strings[4] = "mno";
        strings[5] = "pqrs";
        strings[6] = "tuv";
        strings[7] = "wxyz";

    }

    public List<String> letterCombinations(String digits) {
        this.digits = digits;
        if (digits.length() == 0) return result;
        backTracking(0);
        return result;
    }

    private void backTracking(int startIndex) {
        if (startIndex != path.size()) return;//剪掉从digit第二个开始遍历后面的情况
        if (path.size() == digits.length()) result.add(getPathStr());

        for (int i = startIndex; i < digits.length(); i++) {
            int index = digits.charAt(i) - 50;
            for (char ch : strings[index].toCharArray()) {
                path.add(ch);
                backTracking(i + 1);
                path.removeLast();
            }
        }

    }

    private String getPathStr() {
        StringBuilder stringBuilder = new StringBuilder();
        for (char c : path) {
            stringBuilder.append(c);
        }
        return stringBuilder.toString();
    }
}

上面就缺什么呢?缺的是对数据的处理的优化,放进链表里还有提取出来,在一个一个地放StringBuilder里,再将StringBuilder转为String类型,如果一开始就是用StringBuilder这个容器来存储,而不是链表来存储不就省去取出链表元素的步骤了吗!

终极版:

public class Solution {
    String[] strings = new String[8];
    List<String> result = new LinkedList<>();
    String digits;
    StringBuilder stringBuilder = new StringBuilder();
    public Solution() {
        strings[0] = "abc";
        strings[1] = "def";
        strings[2] = "ghi";
        strings[3] = "jkl";
        strings[4] = "mno";
        strings[5] = "pqrs";
        strings[6] = "tuv";
        strings[7] = "wxyz";

    }

    public List<String> letterCombinations(String digits) {
        this.digits = digits;
        if (digits.length() == 0) return result;
        backTracking(0);
        return result;
    }

    private void backTracking(int startIndex) {
        if (startIndex != stringBuilder.length()) return;//剪掉从digit第二个开始遍历后面的情况
        if (stringBuilder.length() == digits.length()) result.add(stringBuilder.toString());

        for (int i = startIndex; i < digits.length(); i++) {
            int index = digits.charAt(i) - 50;
            for (char ch : strings[index].toCharArray()) {
                stringBuilder.append(ch);
                backTracking(i + 1);
                stringBuilder.deleteCharAt(stringBuilder.length() - 1);
            }
        }

    } 
}

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

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

相关文章

【踩坑专栏】关于实现异步多线程的一些踩坑

在实现基于redis的分布式锁的时候&#xff0c;有一项功能&#xff0c;就是通过开启异步线程&#xff0c;对还没有unlock的key进行定时刷新&#xff0c;延长时间。 初始版本是New一个线程start。我们知道New一个线程&#xff0c;用了没多久又抛弃&#xff0c;这种方法非常消耗资…

【浅学Java】SpringBoot 日志文件

SpringBoot 日志文件1. 认识日志文件1.1. 日志文件有什么用&#xff1f;1.2 日志文件的格式2. 自定义日志文件的打印3. 日志的持久化3.0 什么时日志持久化3.1 设置日志名称3.2 设置日志目录3.3 持久化日志的特点4. 日志的级别5. 设置“日志级别”来筛选日志6. 简化日志打印——…

量子计算(十二):量子线路与测量操作

文章目录 量子线路与测量操作​​​​​​​ 量子线路与测量操作​​​​​​​ 量子线路是由代表量子比特演化的路线和作用在量子比特上的量子逻辑门组成的。量子线路产生的效果&#xff0c;等同于每一个量子逻辑门依次作用在量子比特上。在真实的量子计算机上&#xff0c;最…

HTML CSS游戏官网网页模板 仿绝地求生吃鸡游戏网站 大学生游戏介绍网站毕业设计 DW游戏主题网页模板下载

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

[附源码]Python计算机毕业设计Django影院管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

使用yum info查看软件包信息与常用软件包

记录&#xff1a;357 场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;使用yum info查看软件包信息&#xff0c;包括软件包名称、适用架构、版本号、发行版、软件大小、仓库名称、概要、URL、许可证、描述。 版本&#xff1a; 操作系统&#xff1a;CentOS 7.9 1.iptabl…

【现代机器人学】学习笔记三:前向运动学(Forward Kinematics)

这节的内容比较简单&#xff0c;主要配合习题来看。 在掌握方法以后&#xff0c;对常规的有许多移动副或转动副结构组成的机械臂&#xff0c;计算正向运动学则非常简单。 齐次变换法&#xff1a; 这种方法的特点是&#xff0c;只研究当前关节和上一个关节的旋转平移&#xf…

供应商关系管理与企业内容管理 (ECM) 相结合,帮助解决采购存在的五个关键挑战

供应商关系管理与企业内容管理 &#xff08;ECM&#xff09; 相结合&#xff0c;帮助解决采购存在的五个关键挑战 采购过程包括将制造需求转化为供应商需求、如何管理供应商关系、以及生产产品所需的商品和服务的订购。 领先的制造、制药、食品和自然资源组织正在意识到&#…

【性能优化】pc端与移动端图片性能优化

目录 优化方向 优化方式 1.域名收敛 2.使用CDN节点 3.设置缓存 4.图片懒加载 5.用户图片上传限制 6.使用OSS服务压缩 7.使用OSS缩放 8.合成雪碧图 9.使用svg图片 在前端项目中图片的性能优化也有不少可以提升的地方&#xff0c;那么有哪些性能优化的点呢&#xff1f…

[附源码]Python计算机毕业设计Django游戏交易平台

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

NEMUCOD病毒jse样本分析

该病毒使用微软的JScript编写&#xff0c;能够直接运行在Windows操作系统之上&#xff0c;采用了加密和混淆手段对抗监测&#xff0c;可检测是否运行在虚拟机中和系统中是否存在分析工具&#xff0c;可感染可移动存储介质&#xff0c;主要功能为下载器。CC服务器为185.159.82.1…

牛客网刷题【BC114\BC123\BC125\BC13\BC93\BC95】

目录 一、BC114 小乐乐排电梯 二、BC123 小乐乐找最大数 三、BC125 小乐乐转换成绩 四、BC13 ASCII码 五、BC93 统计数据正负个数 六、BC95 最高分与最低分之差 一、BC114 小乐乐排电梯 #include <stdio.h>int main() {int n0;scanf("%d",&n…

Aspose.Words 22.12.0 for NET cRACK

.NET API 来处理 Word 文件 无需使用外部软件即可创建、编辑、呈现 Word 文档并将其转换为多种格式。您还可以生成报告以可视化数据。 .NET 的 Aspose.Words Aspose.Words for .NET 是一种高级文档处理 API&#xff0c;可对各种文件格式执行广泛的管理和操作任务。API 支持…

(文章复现)5.基于BP神经网络的风电功率预测方法(MATLAB程序)

联系方式&#xff1a;2645521500 复现文章&#xff1a; 基于BP神经网络的风电功率预测方法——刘立群&#xff08;2021年&#xff09; 摘要&#xff1a; 风电功率预测结果的准确性&#xff0c;不仅关系到风力发电厂的综合运行效率&#xff0c;也与区域运行成本具备直接联系…

Java面试-MySQL事务专题

链接&#xff1a;https://pan.baidu.com/s/1mw4sej8BzdHNCkaib4ebeg 提取码&#xff1a;j2qu 1 事务的四个特点是什么&#xff1f;他们是如何实现的&#xff1f; ACID-原子性、一致性、隔离性和持久性。 ACID原理原子性undolog一致性通过其他三个特性来实现的隔离性锁MVCC持…

java计算机毕业设计ssm校园志愿者服务系统u7thd(附源码、数据库)

java计算机毕业设计ssm校园志愿者服务系统u7thd&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xf…

初学者必刷题---PTA基础编程题目集第一期

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​ &#x1f4e3;系列专栏&#xff1a;初学者必刷题—鹏哥推荐 &#x1f4ac;总结&#xff1a;希望…

STC 51单片机62—— Proteus仿真多位数码管稳定显示 不抖动

#include<reg52.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int //uchar code dis_code[]{0x80,0xf8,0x82,0x92,0x99,0xb0,0xa4,0xf9}; //共阳数码管段码表 //共阴字形码表【实验】数码管实验时&#xff0c;一定要将点阵模块跳…

玩转系统|如何Windows Update自动更新

目录 为什么要关闭Windows自动更新&#xff1f; 1、防止在工作时间突然中断计算机。 2、应用程序兼容性变差。 可能会导致系统损坏。 关闭Windows自动更新的几种方法&#xff01; 方法一&#xff1a;通过Windows设置关闭Windows自动更新 方法二&#xff1a;通过组策略编…

如何查看浏览器页面缓存内容(代码控制台)【详细教程】

如何查看浏览器页面缓存内容——代码&控制台知识调用前言引入控制台输入代码查看在控制台application查看知识调用 文章可能需要用到的知识&#x1f525;&#x1f525;&#x1f525;浏览器缓存有哪些&#xff08;通用缓存有哪些&#xff09; 前言引入 浏览器有多种缓存&a…