算法学习 | 回溯算法之深度优先搜索常见题型练习

news2024/11/29 22:54:03

目录

岛屿的最大面积

电话号码的字母组合 

二进制手表 

组合总数 

活字印刷


岛屿的最大面积

题目链接:leetcode-695.岛屿的最大面积

示例 

输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]

输出:6

题目分析 

由题意知,在这个二维数组中,有很多陆地,因此维护一个最大面积,一个临时面积,一个标记数组。遍历二维数组的每一个位置,当遇到陆地且该陆地未被标记过时,就进行搜索,搜索的方式为,从该陆地开始,遍历其上下左右,再遍历每个位置的上下左右,直至遇到边界或海洋或该陆地已被标记过为止。 

class Solution {
    int ret;
    int tmpArea;
    public int maxAreaOfIsland(int[][] grid) {
        if (grid == null || grid[0].length == 0) {
            return 0;
        }
        int m = grid.length;
        int n = grid[0].length;
        int[][] book = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1 && book[i][j] == 0) {
                    tmpArea = 0;
                    dfs(grid, book, i, j);
                    ret = Math.max(ret, tmpArea);
                }
            }
        }
        return ret;
    }
    private void dfs(int[][] grid, int[][] book, int row, int col) {
        if (row < 0 || row >= grid.length || col < 0 || col >= grid[0].length || grid[row][col] == 0) {
            return ;
        }
        if (book[row][col] == 1) {
            return ;
        }
        book[row][col] = 1;
        tmpArea++;
        dfs(grid, book, row + 1, col);
        dfs(grid, book, row - 1, col);
        dfs(grid, book, row, col + 1);
        dfs(grid, book, row, col - 1);
    }
}

电话号码的字母组合 

题目链接:leetcode-17.电话号码的字母组合

示例 

输入:digits = "23"

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

题目分析

根据题意,每个数字表示几个字符,因此,定义一个字符串数组来记录每个数字所代表的几个字符

String[] mapString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};

 维护一个深度和当前的可能的字母组合,当输入的数字长度等于深度时,就将当前的字母组合加入到结果集中,结束该路径并继续向上回溯;根据深度找到当前的数字,再根据这个数字得到该数字所代表的字符,依次遍历每一种可能,直至所有字符遍历结束。

class Solution {
    String[] mapString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    List<String> ret = new ArrayList<>();
    public List<String> letterCombinations(String digits) {
        if (digits == null || digits.length() == 0) {
            return new ArrayList<>();
        }
        StringBuilder curStr  = new StringBuilder("");
        dfs(digits, curStr, 0);
        return ret;
    }
    private void dfs(String digits, StringBuilder curStr, int curDepth) {
        if (curDepth == digits.length()) {
            ret.add(curStr.toString());
            return ;
        }
        int curIndex = digits.charAt(curDepth) - '0';
        String curMap = mapString[curIndex];
        for (int i = 0; i < curMap.length(); i++) {
            dfs(digits, curStr.append(curMap.charAt(i)), curDepth + 1);
            curStr.deleteCharAt(curStr.length() - 1);
        }
    }
}

二进制手表 

题目链接:leetcode-401.二进制手表

二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。

给你一个整数 turnedOn ,表示当前亮着的 LED 的数量,返回二进制手表可以表示的所有可能时间。你可以 按任意顺序 返回答案。

小时不会以零开头:例如,"01:00" 是无效的时间,正确的写法应该是 "1:00" 。

分钟必须由两位数组成,可能会以零开头:例如,"10:2" 是无效的时间,正确的写法应该是 "10:02" 。

 

 例如

输入:turnedOn = 1

输出:["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"]

题目分析

表示时的有1,2,4,8,表示分的有1,2,4,8,16,32,分别定义两个数组用来存储时的可能数字和分的可能数字。由于题目中要求小时0~11,分钟0~59,因此表示时的灯最多亮三个,表示分的灯最多亮5个,因此给定的数字需在0~8之间。依次从每一个时和分进行深度优先搜索,当分钟和大于59或小时和大于11就返回,当深度达到给定的数字时,拼接时和分将其加入到结果集中。

class Solution {
    int[] hours = {1, 2, 4, 8};
    int[] minutes = {1, 2, 4, 8, 16, 32};
    List<String> ret = new ArrayList<>(); 
    public List<String> readBinaryWatch(int turnedOn) {
        if (turnedOn < 0 || turnedOn >= 9) {
            return new ArrayList<>();
        }
        dfs(turnedOn, 0, 0, 0, 0, 0);
        return ret;
    }
    private void dfs(int turnedOn, int hour, int min, int i, int j, int curDepth) {
        if (min > 59 || hour > 11) {
            return ;
        }
        if (curDepth == turnedOn) {
            StringBuilder cur = new StringBuilder();
            cur.append(hour);
            if (min < 10) {
                cur.append(":0" + min);
            } else {
                cur.append(":" + min);
            }
            ret.add(cur.toString());
            return ;
        }
        for (; i < hours.length; i++) {
            hour += hours[i];
            dfs(turnedOn, hour, min, i + 1, j, curDepth + 1);
            hour -= hours[i];
        }
        for (; j < minutes.length; j++) {
            min += minutes[j];
            dfs(turnedOn, hour, min, i, j + 1, curDepth + 1);
            min -= minutes[j];
        }
    }
}

组合总数 

题目链接:leetcode-39.组合总数

示例

输入:candidates = [2,3,6,7], target = 7

输出:[[2,2,3],[7]]

题目分析:

由于同一个数字可以无限制重复被选取,因此每次从上一个位置开始搜索,边界值的设定:当目前的累加值大于给定的值就返回,当累加值等于给定的值就将其加入结果集中。

class Solution {
    List<List<Integer>> ret = new ArrayList<>();
    List<Integer> curRet = new ArrayList<>();
    int curSum;
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        dfs(candidates, target, 0);
        return ret;
    }
    private void dfs(int[] candidates, int target, int pre) {
        if (curSum > target) {
            return ;
        }
        if (curSum == target) {
            ret.add(new ArrayList<>(curRet));
            return ;
        }
        for (int i = pre; i < candidates.length; i++) {
            if (candidates[i] > target) {
                continue;
            }
            curSum += candidates[i];
            curRet.add(candidates[i]);
            dfs(candidates, target, i);
            curSum -= curRet.get(curRet.size() - 1);
            curRet.remove(curRet.size() - 1);
        }
    }
}

活字印刷

题目链接:leetcode-1079.活字印刷

 

示例

输入:"AAB"

输出:8 

题目分析

 按照题意tiles中每一个位置的字符在组合中只能出现一次,所以可以用一个标记辅助当去组合新的组合时,可以与tiles中的每一个位置组合,但是如果当前位置已经在当前组合中出现过,则跳过 虽然此题中每一个位置的字符在组合中只能出现一次,但是tiles中可能有相同的字符,所以需要考虑重复的组合,使用HashSet可以实现去重

class Solution {
    public int numTilePossibilities(String tiles) {
        Set<String> ret = new HashSet<>();
        List<Integer> usedIndex = new ArrayList<>();
        for (int i = 0; i < tiles.length(); i++) {
            usedIndex.add(0);
        }
        StringBuilder curStr = new StringBuilder("");
        dfs(tiles, curStr, usedIndex, ret);
        return ret.size();
    }
    private void dfs(String tiles, StringBuilder curStr, List<Integer> usedIndex, Set<String> ret) {
        if (curStr.length() != 0) {
            ret.add(curStr.toString());
        }
        for (int i = 0; i < tiles.length(); i++) {
            if (usedIndex.get(i) == 1) {
                continue;
            }
            usedIndex.set(i, 1);
            dfs(tiles, curStr.append(tiles.charAt(i)), usedIndex, ret);
            usedIndex.set(i, 0);
            curStr.deleteCharAt(curStr.length() - 1);
        }
    }
}

 

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

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

相关文章

线程“八锁“ synchronized到底是对哪个对象加锁?

线程"八锁" synchronized到底是对哪个对象加锁? 习题一 class Number{public synchronized void a(){System.out.println("1");}public synchronized void b(){System.out.println("2");} } public class TestBlock {public static void main(…

从Zemax OpticStudio导入光学系统

摘要 ZemaxOpticStudio是一款广泛使用的光线追迹软件。VirtualLab Fusion可以从Zemax OpticStudio导入光学系统&#xff0c;包括完整3D位置信息和镜片玻璃。导入后&#xff0c;光学系统的结构数据将显示为单独的表面或可以组合成VirtualLab Fusion中的组件。VirtualLab Fusion可…

docker入门(一):在centOS虚拟机上安装docker

索引CentOS虚拟机安装1.下载CentOS镜像问题1-报错“您已输入用户名&#xff0c;客户机操作系统将保留此用户名”2.根据docker官方指导进行安装1.卸载旧版本&#xff08;初次安装可以忽略&#xff09;2.确保能联网后下载前置软件包3.设置镜像库&#xff08;阿里版&#xff09;4.…

CLIP后续--LSeg,GroupViT,ViLD

这个博客开了有两个月&#xff0c;一直没写成&#xff0c;最近封寝给它完成~躺平第三天 CLIP应用领域概览&#xff1a; 1. LSeg 原论文地址&#xff1a;https://arxiv.org/abs/2201.03546 代码&#xff1a;https://github.com/isl-org/lang-seg 这个图就很清楚的说明了zero…

mysql数据库管理

目录 一、MySQL数据库管理 1、库和表 2、常用的数据类型 3、char和varchar区别 二、查看数据库结构 三、SQL语句 1、SQL语句分类&#xff1a; 四、创建及删除数据库和表 五、管理表中的数据记录 六、修改表名和表结构 七、自增 八、填充 九、克隆表 十、清空表&am…

信号与系统1——Signals and Systems

信号与系统1——Signals and Systems一、Introduction1. Signals and Systems信号与系统(1) Signal信号(2) System系统2. Classification of Signals信号的分类(1) Continuous-time & discrete-time1) Continuous-Time signal连续时间信号2) Discrete-Time signal离散时间信…

【Hack The Box】linux练习-- Passage

HTB 学习笔记 【Hack The Box】linux练习-- Passage &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年9月7日&#x1f334; &#x1f36…

浅析数据仓库和建模理论

第一章 认识数据仓库 1.1 数据仓库概念 数据仓库&#xff0c;英文名称为 Data Warehouse&#xff0c;可简写为 DW 或 DWH。数据仓库&#xff0c;是为企业所有级别的决策制定过程&#xff0c;提供所有类型数据支持的战略集合。它是单个数据存储&#xff0c;出于分析性报告和决…

BDD - SpecFlow SpecRun Web UI 多浏览器测试

BDD - SpecFlow & SpecRun 一个 Cases 匹配多个浏览器引言方案SpecFlow Runner profiles实现被测 Web Application创建一个 Class Libary 项目添加 NuGet PackagesSpecFlow & SpecRun 包添加 Selenium包其它包创建 Feature 文件配置 Default.srprofileDefault.srprofil…

MySQL的概念

MySQL的概念一.数据库的基本概念1、数据&#xff08;Data&#xff09;2、表3、数据库4、数据库管理系统&#xff08;DBMS&#xff09;4.1 关系数据库4.2 非关系型数据库 NoSQL5、数据库系统6、访问数据库的流程二.数据库系统发展史1.第一代数据库2.第二代数据库3.第三代数据库三…

JAVA多线程(MultiThread)的各种用法

多线程简单应用 单线程的问题在于&#xff0c;一个线程每次只能处理一个任务&#xff0c;如果这个任务比较耗时&#xff0c;那在这个任务未完成之前&#xff0c;其它操作就会无法响应。 如下示例中&#xff0c;点击了“进度1”后&#xff0c;程序界面就没反应了&#xff0c;强行…

类文件结构和初识一些字节码指令

文章目录类文件的结构为什么要了解字节码指令Class文件结构Java虚拟机规定的类结构魔数版本常量池访问标志类索引、父类索引、接口索引Ⅰ. interfaces_count&#xff08;接口计数器&#xff09;Ⅱ. interfaces[]&#xff08;接口索引集合&#xff09;字段表集合**1. 字段表访问…

【React】使用 react-pdf 将数据渲染为pdf并提供下载

文章目录前言环境步骤1. 安装react脚手架2. 使用 create-react-app 创建项目 &#xff08;首字母不要大写、不要使用特殊字符&#xff09;3. 用 vscode 打开目录 react-staging4. yarn 启动项目5. 参考 react-pdf readme加入依赖6. 结合 github readme 和官方文档产出 demo 代码…

OpenGL 色彩替换

目录 一.OpenGL 色彩替换 1.IOS Object-C 版本1.Windows OpenGL ES 版本2.Windows OpenGL 版本 二.OpenGL 色彩替换 GLSL Shader三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录…

防抖debounce与节流throttle(63rd)

一、前言 当用户高频触发某一事件时&#xff0c;如窗口的resize、scroll&#xff0c;输入框内容校验等&#xff0c;此时这些事件调用函数的频率如果没有限制&#xff0c;可能会导致响应跟不上触发&#xff0c;出现页面卡顿&#xff0c;假死现象。此时&#xff0c;我们可以采用…

深度剖析NIKE Web3平台:为什么Web3对品牌很重要?

欢迎关注沉睡者IT&#xff0c;点上面关注我 ↑ ↑ 上周&#xff0c;NIKE 宣布了其新的 Web 3 平台 .SWOOSH&#xff0c;这是 NIKE Virtual Sudios (耐克虚拟工作室) 的一项新举措&#xff0c;将成为 NIKE 所有数字资产创作的“大本营”。继去年收购 RTFKT 之后&#xff0c;此次…

SpringBoot SpringBoot 原理篇 3 核心原理 3.4 启动流程【3】

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇3 核心原理3.4 启动流程【3】3.4.1 看源码咯3 核心原理 3.4 启动流程【3】 …

负载均衡反向代理下的webshell上传

目录 架构如下&#xff1a; 实验环境&#xff1a; AntSword-Labshttps://github.com/AntSwordProject/AntSword-Labs 搭建环境&#xff1a; 启动环境&#xff1a; 测试连接&#xff1a; 地址不停的在漂移会造成的问题&#xff1a; 难点一&#xff1a;我们需要在每一台节点…

特征工程(六)—(2)利用LDA进行特征转换

1、LDA的手动处理 LDA&#xff08;线性判别分析&#xff09;是特征变换算法&#xff0c;也是有监督分类器。 和PCA一样&#xff0c;LDA的目标是提取一个新的坐标系&#xff0c;将原始的数据集投影到一个低维的空间中。 和PCA的主要区别是&#xff0c;LDA不会专注数据的方差&a…

[附源码]计算机毕业设计JAVA实验教学过程管理平台

[附源码]计算机毕业设计JAVA实验教学过程管理平台 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM my…