2024.06.24 刷题日记

17. 电话号码的字母组合

依然是昨天的回溯,思路是根据 index,来确定要回溯的对象:

class Solution {
public:vector<string> letterCombinations(string digits) {vector<string> results;if (digits.empty())return results; // 处理空输入// 数字到字母的映射vector<string> posi = {"",    "",    "abc",  "def", "ghi","jkl", "mno", "pqrs", "tuv", "wxyz"};string current; // 当前正在构建的字符串backtrack(digits, 0, current, posi, results);return results;}void backtrack(const string& digits, int index, string& current,const vector<string>& posi, vector<string>& results) {if (digits.size() == current.size()) {results.push_back(current);return;}int pos = digits[index] - '0';string letters = posi[pos];for (auto letter : letters) {current.push_back(letter);backtrack(digits, index + 1, current, posi, results);current.pop_back();}}
};

22. 括号生成

这道题目挺难,这里的思路是利用两个规则来构建合法的括号表达式:

		if (open < max) {current.push_back('(');}if (close < open) {current.push_back(')');}

如果左括号小于 max,就加,如果右括号小于左括号,就加。这两个规则可以确保生成的括号表达式是合法的。因为这在根本上就规避了这样的组合:)((...())...

class Solution {
public:vector<string> generateParenthesis(int n) {vector<string> result;string current;backtrack(result, current, 0, 0, n);return result;}void backtrack(vector<string>& result, string& current, int open, int close,int max) {if (current.size() == max * 2) {result.push_back(current);return;}if (open < max) {current.push_back('(');backtrack(result, current, open + 1, close, max);current.pop_back();}if (close < open) {current.push_back(')');backtrack(result, current, open, close + 1, max);current.pop_back();}}
};

79. 单词搜索

这个题目还是回溯,需要一个 helper 数组来标记已经访问过的位置,并且回溯过程中,递归函数也是带有返回值的。在调用函数中,需要对每个位置进行搜索,如果搜索到就返回,相当于示例优化;在被调用函数中,如果board[x][y] != word[index]就返回 false,相当于剪枝,因此整个过程时间复杂度并不高:

class Solution {
public:bool exist(vector<vector<char>>& board, string word) {int m = board.size(), n = board[0].size();vector<vector<bool>> visited(m, vector<bool>(n, false));for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (search(board, word, 0, i, j, visited))return true;}}return false;}private:bool search(vector<vector<char>>& board, string& word, int index, int x,int y, vector<vector<bool>>& visited) {if (index == word.size())return true;if (x < 0 || x >= board.size() || y < 0 || y >= board[0].size() ||visited[x][y] || board[x][y] != word[index])return false;visited[x][y] = true;bool found = search(board, word, index + 1, x + 1, y, visited) ||search(board, word, index + 1, x - 1, y, visited) ||search(board, word, index + 1, x, y + 1, visited) ||search(board, word, index + 1, x, y - 1, visited);visited[x][y] = false;return found;}
};

131. 分割回文串

这个题目的核心思路是剪枝:当 (s,index,i) 是回文串的时候,纵向深入:

class Solution {
public:vector<vector<string>> partition(string s) {vector<vector<string>> result;vector<string> path;backtrace(s, 0, path, result);return result;}private:void backtrace(string& s, int index, vector<string>& path,vector<vector<string>>& result) {if (index == s.size()) {result.push_back(path);return;}for (int i = index; i < s.size(); i++) {if (isPalindrome(s, index, i)) {path.push_back(s.substr(index, i - index + 1));backtrace(s, i + 1, path, result);path.pop_back();}}}bool isPalindrome(string& str, int start, int end) {while (start < end) {if (str[start] != str[end]) {return false;}start++;end--;}return true;}
};

51. N 皇后

N 皇后相关的题目很多,但是都大同小异。这个题目的难点在于如果去标记纵向、两个对角线是否被占用,对于第 row 行、col 列,那么对角线为:diag1[row - col + n - 1]diag2[row + col]。其中:

vector<bool> diag1(2 * n - 1, false); // 左下到右上
vector<bool> diag2(2 * n - 1, false); // 左上到右下

最好把这个记住,可以加快做题速度。

解决了这个问题之后,其他就很简单了,在 row 上进行回溯就行了:

class Solution {
public:vector<vector<string>> solveNQueens(int n) {vector<vector<string>> solutions;vector<string> board(n, string(n, '.'));vector<bool> cols(n, false);vector<bool> diag1(2 * n - 1, false);vector<bool> diag2(2 * n - 1, false);backtrack(solutions, board, cols, diag1, diag2, 0, n);return solutions;}private:void backtrack(vector<vector<string>>& solutions, vector<string>& board,vector<bool>& cols, vector<bool>& diag1, vector<bool>& diag2,int row, int n) {if (row == n) {solutions.push_back(board);return;}for (int col = 0; col < n; ++col) {if (cols[col] || diag1[row - col + n - 1] || diag2[row + col]) {continue;}board[row][col] = 'Q';cols[col] = diag1[row - col + n - 1] = diag2[row + col] = true;backtrack(solutions, board, cols, diag1, diag2, row + 1, n);board[row][col] = '.';cols[col] = diag1[row - col + n - 1] = diag2[row + col] = false;}}
};

总结

这些题目都是经典的回溯算法问题,每个问题都利用了回溯的核心思想:探索所有可能的解决方案,并在遇到死路时撤销上一步或几步的决定(回溯),然后尝试其他可能的选项。以下是每个问题的详细解析和核心思想。

17. 电话号码的字母组合

核心思想:对于每个数字字符,有一组对应的字母。使用回溯法逐一探索每个数字对应的所有字母,组合成所有可能的字母组合。

解题步骤

  1. 创建一个映射列表posi,将每个数字映射到相应的字符串。
  2. 使用递归函数backtrack,从左到右处理每个数字,并尝试每个数字对应的所有可能字母。
  3. 当当前组合的长度等于输入数字字符串的长度时,将其添加到结果列表中。

22. 括号生成

核心思想:确保在任何时刻插入的右括号数量不超过左括号的数量,从而确保生成的括号字符串有效。

解题步骤

  1. 使用递归函数backtrack,维护当前的括号字符串和左、右括号的计数。
  2. 如果左括号数量小于n,可以添加一个左括号并递归。
  3. 如果右括号数量小于左括号数量,可以添加一个右括号并递归。
  4. 当字符串长度达到2*n时,说明找到了一个有效的组合,添加到结果中。

79. 单词搜索

核心思想:在二维网格中使用回溯法搜索每个单元格,尝试找到目标单词的路径。

解题步骤

  1. 遍历整个网格,以每个单元格作为起点尝试搜索单词。
  2. 使用递归函数search,探索上下左右四个方向寻找单词的下一个字符。
  3. 使用一个辅助数组visited标记已访问过的单元格,防止重复访问。
  4. 如果在某个方向上的探索成功,返回true;如果所有方向都失败,回溯到上一步。

131. 分割回文串

核心思想:递归地尝试所有可能的分割方案,并使用剪枝策略只保留那些分割后是回文的结果。

解题步骤

  1. 递归函数backtrace从索引index开始尝试所有可能的分割点。
  2. 对于每个可能的分割点,检查从index到当前点的子字符串是否是回文。
  3. 如果是回文,则将其添加到当前路径中,并从下一个位置继续尝试。
  4. 当达到字符串末尾时,将当前路径添加到结果中。

51. N 皇后

核心思想:在n*n的棋盘上放置n个皇后,使得它们互不攻击。这通过确保每行、每列及两个方向的对角线上最多只有一个皇后来实现。

解题步骤

  1. 使用递归函数backtrack探索每一行的所有列,尝试放置皇后。
  2. 通过三个布尔数组cols, diag1, diag2来检查当前列和对角线上是否已放置皇后。
  3. 如果找到有效的位置,放置皇后并递归地尝试下一行。
  4. 如果所有行都成功放

置了皇后,记录当前的棋盘配置。
5. 否则回溯,尝试当前行的其他列。

每个问题都采用了回溯策略,这种策略不仅能找到一个解,还能找到所有可能的解,并在适当的时候进行剪枝,优化搜索过程。

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

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

相关文章

Linux 运维王者从不离手的10款工具

运维工程师在日常工作中频繁运用的10款工具&#xff0c;并细致阐述每款工具的功能、适用场景以及其卓越之处。 1. Shell脚本 功能&#xff1a;主要用于自动化任务和批处理作业。 适用场景&#xff1a;频繁用于文件处理、系统管理、简单的网络管理等操作。 优势&#xff1a;灵…

Java 抽象类

目录 1、什么是抽象类 2、定义抽象类 3、抽象类特性 4、 抽象类的作用 1、什么是抽象类 抽象类&#xff0c;顾名思义就是抽象的。该类没有包含足够的信息去描绘一个具体的对象&#xff0c;这样的类称为抽象类。抽象类着一种优化了的概念组织方式&#xff0c;它是所有子类的…

研究上百个小时,高手总结了这份 DALL-E 3 人物连续性公式(上)

上篇 Dall-E 3 讲了常见的 20 个公式&#xff0c;今天单独来讲一下人物连续性公式&#xff0c;这个公式来自 AshutoshShrivastava。 上篇回顾&#xff1a; 效果超好&#xff01;全新 DALL-E 3 必须掌握的 20 种公式使用方法上周末&#xff0c;DALL-E 3 正式加入 ChatGpt&…

嵌入式实验---实验八 ADC电压采集实验

一、实验目的 1、掌握STM32F103ADC电压采集程序设计流程&#xff1b; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、使用STM32F103R6采集可变电阻上的电压信号&#xff0c;并通过计算把当前ADC转换值和电压值显示在LCD1602液晶屏上&#xff1b; 2、对照电压表读数&…

红队内网攻防渗透:内网渗透之内网对抗:横向移动篇域控系统提权NetLogonADCSPACKDC永恒之蓝CVE漏洞

红队内网攻防渗透 1. 内网横向移动1.1 横向移动-域控提权-CVE-2020-1472 NetLogon1.2 横向移动-域控提权-CVE-2021-422871.3 横向移动-域控提权-CVE-2022-269231.4 横向移动-系统漏洞-CVE-2017-01461.5 横向移动-域控提权-CVE-2014-63241. 内网横向移动 1、横向移动-域控提权-…

【问题】Ubuntu下使用ftp命令下载文件

Ubuntu下使用ftp命令下载文件具体的方法示例如下: $ ftp 192.168.180.3 Connected to 192.168.180.3. Name (192.168.180.3:test): 此处输入用户名 Password:此处输入对应的密码 /*查看当前路径*/ ftp> pwd 257 "/" is current directory. ftp> cd test …

为冲刺IPO,喜马拉雅曝裁员20%?钉钉叶军吐槽百度搜索;美国制裁俄罗斯安全软件12名高管;华为自研语言仓颉力战Java

一、商业圈 1.钉钉总裁叶军吐槽百度搜索&#xff1a;前十条都是广告 钉钉总裁叶军在亚布力中国企业家论坛第十届创新年会上发表了演讲&#xff0c;期间他直言不讳地对百度搜索提出了批评。叶军指出&#xff0c;在OpenAI推出智能聊天机器人ChatGPT之后&#xff0c;百度的传统搜…

C++系统相关操作5 - 获取C++标准的版本

1. 关键词2. sysutil.h3. sysutil.cpp4. 测试代码5. 运行结果6. 源码地址 1. 关键词 关键词&#xff1a; C 标准库 STL 版本 指令集 跨平台 应用场景&#xff1a; 根据C的版本决定使用不同的函数接口打印系统日志。 2. sysutil.h #pragma once#include <cstdint> …

【Web APIs】JavaScript 事件基础 ② ( “ 事件 “ 开发步骤 | 常见鼠标 “ 事件 “ )

文章目录 一、" 事件 " 开发步骤1、" 事件 " 开发步骤2、完整代码示例 二、常见鼠标 " 事件 "1、常见鼠标 " 事件 "2、鼠标 " 事件 " 代码示例 Web APIs 博客相关参考文档 : WebAPIs 参考文档 : https://developer.mozilla…

Linux中Vim的使用技巧总结

日常工作中&#xff0c;Vim使用方式&#xff1a; 功能命令说明光标移动h向左移动光标j向下移动光标k向上移动光标l向右移动光标w移动到下一个单词的开始处e移动到下一个单词的结束处b移动到上一个单词的开始处0 (数字零)移动到当前行的开始处$移动到当前行的末尾gg移动到文件的…

6个步骤实现 Postman 接口压力测试

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、第一步接口可以通的情况下点击右上角save 2、将相应信息填入 3、如果是同一个接口修改不同的…

大型国民老牌药品医疗企业如何借助实时数仓冲破数据孤岛桎梏,拥抱数据驱动的经营管理模式

使用 TapData&#xff0c;化繁为简&#xff0c;摆脱手动搭建、维护数据管道的诸多烦扰&#xff0c;轻量代替 OGG、DSG 等同步工具&#xff0c;「CDC 流处理 数据集成」组合拳&#xff0c;加速仓内数据流转&#xff0c;帮助企业将真正具有业务价值的数据作用到实处&#xff0c…

Mysql: 数据模型

一.关系型数据库 概念:建立在关系型基础上,由多张相互连接的二维表组成的数据库。 1.关系型数据库: 2.特点&#xff1a; 1.使用表存储数据,格式统一,便于维护。 2.使用SQL语言操作,标准统一,使用方便。 3.数据模型 通过客户端连接DBMS可以创建多个数据库,在数据库中…

如何在Java中处理ParseException异常?

如何在Java中处理ParseException异常&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java编程中&#xff0c;ParseException异常是开发者在处理…

322. 零钱兑换-c语言

322. 零钱兑换-c语言 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬…

光伏半导体的种类

光照射半导体材料时&#xff0c;其电导率发生变化的实质是光生载流子的产生。在半导体中&#xff0c;价带中的电子受到一定能量的光子激发后&#xff0c;可以跃迁到导带&#xff0c;形成自由电子和空穴对&#xff0c;即光生载流子。这些光生载流子会增加半导体的导电能力&#…

ZOOM太卡怎么办?公司如何解决ZOOM会议卡顿?

ZOOM作为一种常见的办公工具&#xff0c;尤其在跨国公司和外资企业中&#xff0c;在线会议非常普遍。然而&#xff0c;由于ZOOM的服务器部署在国外&#xff0c;国内用户使用时可能会遇到卡顿、不稳定和声音断续等问题。那么&#xff0c;如何有效解决ZOOM卡顿的问题呢&#xff1…

「AIGC」LangChain

LangChain 是一个开源的自然语言处理(NLP)框架,它旨在帮助开发者快速构建和部署基于语言模型的应用程序。以下是一份针对初学者的快速入门指南,将帮助你了解LangChain的基本概念和如何开始使用它。 1. LangChain 简介 LangChain 是一个基于 Python 的库,它提供了一系列的…

2024国有企业数字化转型的意义和作用是什么?

一、当下国有企业数字化转型最新的意义及作用是什么? 数字化转型对国有企业具有深远的意义&#xff0c;不仅是企业的内在需求&#xff0c;更是国家经济发展的重要支撑。据研究表明&#xff0c;数字化相关技术可为企业提升约60%的作业效率&#xff0c;降低20%的人力成本&#…

C++核心知识

一、类 类的声明: class 类名 { [public:] [数据成员声明] [函数成员声明] [private:] [数据成员声明] [函数成员声明] [protected:] [数据成员声明] [函数成员声明] } 类函数成员的实现 类声明体内直接实现 类体外&#xff0c;使用域预算符&#xff08;::&#xff09; 如 sho…