2018年LeetCode高频算法面试题刷题笔记——分割回文串(字符串)

2023-11-02

1.解答之前的碎碎念:

这个题我的想法是:

第一刀依次切在第1——s.length() - 2个元素后面,得到两个字符串s0和s1。

首先判断s0整体是否为回文,不是则第一刀的位置+1。

然后再检测s1整体是否为回文,并在s1的第1——s1.length() - 2个元素后面切第二刀。

然后判断s10是否为回文,不是则第二刀的位置+1。

然后再检测s11整体是否为回文,并在s11的第1——s11.length() - 2个元素后面切第三刀。

 

以此类推。

 

然后,然后我就不知道代码怎么写了。。。

 

2.问题描述:

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例:

输入: "aab"
输出:
[
  ["aa","b"],
  ["a","a","b"]
]

3.解答思路:

深度优先搜索(DFS):https://blog.csdn.net/whdAlive/article/details/81254975(这个方法和我的想法有点像)

要点摘录:

解题思路就是 DFS,用一个boolean[] 数组记录当前可分割的位置,每一次深搜的过程都是找下一个可以分割的位置。

为了更容易理解,通过代码简单输出执行的流程(代码中 注释掉的输出部分),建议自己捋清楚整个算法的执行流程,以便举一反三,下面给出我整理的流程(只给思路,不涉及分割位置数组的细节)。

实际上对于 s=”aab” 而言,就是三层递归,每层递归向后找能分割的位置:

层1:从下标 0~2 寻找分割位置,对应子串为 aab
层2:从下标 x~2(x为 最外层传入的下标 和 1 中的大值) 寻找分割位置,对应子串为 ab 或 b
层3:从下标 y~2(y为 中间层传入的下标 和 2 中的大者 ) 寻找分割位置,对应子串为 b 或 无

也就是说,这个题建的树的每一层都对应第n次切的位置。第0层就是不切,所以树的根为原字符串“aab”,第一层对应的是只切一刀的结果,即“a”,"ab"和“aa”,"b"。每次递归都检测左边字符串是否为回文,若是,则对右边的字符串进行再切割。

上面那个链接的方法还是有点啰嗦,可以参考这个链接的代码:https://blog.csdn.net/weixin_41413441/article/details/80926957

 

4.相关知识:

递归、回溯和DFS的区别:https://blog.csdn.net/fengchi863/article/details/80086915

要点摘录:

  • 递归是一种算法结构,回溯是一种算法思想。
  • 一个递归就是在函数中调用函数本身来解决问题。
  • 回溯就是通过不同的尝试来生成问题的解,有点类似于穷举,但是和穷举不同的是回溯会“剪枝”。

剪枝的意思也就是说对已经知道错误的结果没必要再枚举接下来的答案了,比如一个有序数列1,2,3,4,5,我要找和为5的所有集合,从前往后搜索我选了1,然后2,然后选3的时候发现和已经大于预期,那么4,5肯定也不行,这就是一种对搜索过程的优化。

回溯搜索是深度优先搜索(DFS)的一种。对于某一个搜索树来说(搜索树是起记录路径和状态判断的作用),回溯和DFS,其主要的区别是,回溯法在求解过程中不保留完整的树结构,而深度优先搜索则记下完整的搜索树。

为了减少存储空间,在深度优先搜索中,用标志的方法记录访问过的状态,这种处理方法使得深度优先搜索法与回溯法没什么区别了。


5.答案:

class Solution {
public:
	vector<vector<string>> partition(string s) {
		vector<vector<string>> result;
        vector<string> tmp;
		cut(s, result, tmp, 0);
		return result;
	}

	void cut(string s, vector<vector<string>> &result, vector<string> tmp, int right_start) {
        if(right_start >= s.length())
        {
            result.push_back(tmp);
            return;
        }

		for (int i = right_start;i < s.length(); i++) //每次cut的可能位置
		{
			if (isPalindrome(s, right_start, i))
			{
				tmp.push_back(s.substr(right_start, i - right_start + 1));
				cut(s, result, tmp, i + 1);
                tmp.pop_back();//注意在第n刀切的位置改变时,要把之前存储的结果删除
            }
            
		}
        return;



	}
	bool isPalindrome(string s, int start, int end) {
		while (start <= end && s[start] == s[end])
		{
			start++;
			end--;
		}
		return start > end;
	}
};

6.类似题目:

leetcode 17题 —— 电话号码的数字组合:

题目:

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

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

示例:

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

思路:

用输入的各个数字对应的字母建一颗树,每个字母都是一个节点,树根为“”。

则第一个输入的数字对应的字母为第一层的节点,第二个数字对应字母为第二层节点,以此类推。

进行DFS就可以得到问题的解。

解答:

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        vector<string> s_all = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        vector<string> s_result;
        if(digits.size() == 0) return s_result;
        combination(digits,s_all,s_result,"",0);
        return s_result;
    }
    void combination(string digits,vector<string> s_all,vector<string> &s_result,string tmp,int count)
    {
        if(count >= digits.size()) {s_result.push_back(tmp); return;}//一条线走到底的结果加入最终的结果
        int index = digits[count] - '0';
        for(int i = 0;i < s_all[index].size();i++) //开启一个分支
        {
            combination(digits,s_all,s_result,tmp+s_all[index][i],count + 1);
        }
        return;
    }
};

leetcode 93题 —— 复原IP地址:

题目:

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

示例:

输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]

思路:

这个题的思路和上一个题很像,用的是回溯法(DFS的特殊情况,存在剪枝)

树的根节点为输入,第一层节点为ip地址中第一个“.”应该加的位置,且每一个“.”要加的位置只有当前子串第一个数字、第二个数字、第三个数字后三个选择。且分割出来的第n段ip地址满足小于256和剩余子串长度小于等于(4-n)*3(也就是剩余子串还符合构成ip地址的条件)。

注意:

“.001.”为非法ip地址。

解答:

class Solution {
public:
	vector<string> restoreIpAddresses(string s) {
		vector<string> result;
		vector<int> cut_point = { 0,0,0 };
		if (s.size() == 0) return result;
		restore(s, s, result, cut_point, 1);
		return result;
	}
	void restore(string s,string s_tmp, vector<string> &result, vector<int> cut_point, int count)
	{
		if (count > 4)
		{
			int i = 0;
			int c = 0;
			string r_tmp = "";
			while (i < s.size())
			{
				r_tmp += s[i];
				if (c < 3 && i == cut_point[c])
				{
					r_tmp += ".";
					c++;
				}
				i++;				
			}
			result.push_back(r_tmp);
			return;
		}
		for (int i = 0; i < 3; i++)
		{
			if (i >= s_tmp.size()) return;
			string tmp = "";
			for (int j = 0; j <= i; j++)
			{
				if (j > 0 && s_tmp[0] == '0') 
				{
					return;
				}
				tmp += s_tmp[j];
			}
			int num_tmp = atoi(tmp.c_str());
			if (num_tmp < 256 && ((s_tmp.size() - i - 1) <= (4 -  count) * 3))
			{
				if (count != 4)
				{
					if(count == 1)	cut_point[count - 1] = i;
					else cut_point[count - 1] = i + cut_point[count - 2] + 1;
				}
				
				string ss = "";
				for (int j = i + 1; j < s_tmp.size();j++)
				{
					ss += s_tmp[j];
				}
				restore(s, ss, result, cut_point, count + 1);
			}
		}
		return;
	}
};

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2018年LeetCode高频算法面试题刷题笔记——分割回文串(字符串) 的相关文章

  • 2018年LeetCode高频算法面试题刷题笔记——验证回文串(字符串)

    1 解答之前的碎碎念 这个题还蛮简单的 大概就是考研机试第一题的水平 所以就不写解法了 2 问题描述 给定一个字符串 验证它是否是回文串 只考虑字母和数字字符 可以忽略字母的大小写 说明 本题中 我们将空字符串定义为有效的回文串 示例 1
  • 有序链表转二叉树

  • 500.键盘行 693.交替位二进制数(java实现)

    键盘行 题目 给定一个单词列表 只返回可以使用在键盘同一行的字母打印出来的单词 键盘如下图所示 示例1 输入 Hello Alaska Dad Peace 输出 Alaska Dad 注意 你可以重复使用键盘上同一字符 你可以假设输入的字符
  • LeetCode·每日一题·722. 删除注释·模拟

    题目 示例 思路 题意 gt 给定一段代码 将代码中的注释删除并返回 由于注释只有两种类型 字符串 表示行注释 表示 和其右侧的其余字符应该被忽略 字符串 表示一个块注释 它表示直到下一个 非重叠 出现的 之间的所有字符都应该被忽略 阅读顺
  • Leetcode刷题笔记:二叉树篇(下)

    1 Leetcode 110 平衡二叉树 难度 递归 迭代 给定一个二叉树 判断它是否是高度平衡的二叉树 本题中 一棵高度平衡二叉树定义为 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1 示例 1 给定二叉树 3 9 20 nu
  • 2018年LeetCode高频算法面试题刷题笔记——分割回文串(字符串)

    1 解答之前的碎碎念 这个题我的想法是 第一刀依次切在第1 s length 2个元素后面 得到两个字符串s0和s1 首先判断s0整体是否为回文 不是则第一刀的位置 1 然后再检测s1整体是否为回文 并在s1的第1 s1 length 2个
  • LeetCode·每日一题·2455. 可被三整除的偶数的平均值·模拟

    作者 小迅 链接 https leetcode cn problems average value of even numbers that are divisible by three solutions 2289199 mo ni zh
  • Leetcode 刷题笔记:哈希表篇

    基本概念 哈希表 根据关键码的值而直接进行访问的数据结构 那么哈希表能解决什么问题呢 一般哈希表都是用来快速判断一个元素是否出现集合里 哈希函数 哈希碰撞 一般哈希碰撞有两种解决方法 拉链法和线性探测法 常见的三种哈希结构 数组array
  • 单链表翻转--Java实现

    问题描述 将单链表的顺序翻转过来 代码实现 定义链表节点 static class ListNode int val ListNode next public ListNode int val ListNode next this val
  • java自定义排序

    java中sort的自定义排序 一 Arrays sort nums 的一般用法 二 最大数 力扣179 三 合并区间 力扣59 四 总结 一 Arrays sort nums 的一般用法 整个数组按照升序排序 若需要降序排序 将数组转置即
  • c++ 数据结构——链表

    1 链表概念 暂略 2 栈的相关题目 2 1 leetcode 237 Delete Node in a Linked List 注意 这个题没有给head Definition for singly linked list struct
  • 2018年LeetCode高频算法面试题刷题笔记——搜索二维矩阵 II(开始之前)

    1 解答之前的碎碎念 这个题一开始我想的很简单 想着是个二维的二分查找 然后提交代码 果不其然出错了 因为并不能保证第i 1行的每个元素都大于第i行 不过想到了递归 也算是有点进步 虽然最后用递归写了一个没有通过 但是自己在vs里测试的没问
  • c++ 数据结构——树

    1 树概念 暂略 2 树的相关题目 2 1 leetcode 104 Maximum Depth of Binary Tree Definition for a binary tree node struct TreeNode int va
  • LeetCode198.打家劫舍(动态规划)

    题目描述 来自LeetCode 思路 这道题和01背包很像 这件房屋偷不偷跟前一间房屋是否偷了有关 比如说这是第i间房屋 如果第i 1间房屋偷了 那第i间房屋就不能再偷 那最大值就跟前i 1间房屋的金额最大值有关 如果第i 1间房屋没偷 那
  • LeetCode·每日一题·1177. 构建回文串检测·前缀和

    作者 小迅 链接 https leetcode cn problems can make palindrome from substring solutions 2309940 qian zhui he zhu shi chao ji xi
  • LeetCode·每日一题·1851. 包含每个查询的最小区间·优先队列(小顶堆)

    题目 示例 思路 离线查询 输入的结果数组queries 是无序的 如果我们按照输入的queries 本身的顺序逐个查看 时间复杂度会比较高 于是 我们将queries 数组按照数值大小 由小到大逐个查询 这种方法称之为离线查询 位运算 离
  • leetcode数组刷题总结与分析

    文章目录 小结 数组中元素的计算 子序列 任意元素 题目一 两数之和 题目15 三数的和 17 四数之和 16 最接近三数之和 167 两数之和 输入有序数组 560 和为k的子数组 523 连续的子数组的和 53 最大子数组和 713 乘
  • 【LeetCode刷题笔记】位运算

    231 2 的幂 解题思路 1 除法 不断循环判断 如果能被 2 整除 就不断除以 2 直到不能被 2 整除为止 最后结果如果是 1
  • 【LeetCode刷题笔记】位运算

    231 2 的幂 解题思路 1 除法 不断循环判断 如果能被 2 整除 就不断除以 2 直到不能被 2 整除为止 最后结果如果是 1
  • 【每日一题】2397. 被列覆盖的最多行数-2024.1.4

    题目 2397 被列覆盖的最多行数 给你一个下标从 0 开始 大小为 m x n 的二进制矩阵 matrix 另给你一个整数 numSelect 表示你必须从 matrix 中选择的 不同 列的数量 如果一行中所有的 1 都被你选中的列所覆

随机推荐

  • 架构--网络关键指标

    架构 网络关键指标 1 QPS Queries Per Second 每秒查询率 是一台服务器每秒能够相应的查询次数 是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准 即每秒的响应请求数 也即是最大吞吐能力 2 TPS Tran
  • Stable Diffusion 系列教程

    目录 1 高清修复 1 1 原理 1 2 基本操作 1 3 优缺点 2 UpScale 放大脚本 2 1 原理 2 2 基本操作 2 3 优缺点 3 附加功能放大 3 1 原理 3 2 基本操作 3 3 优缺点 优化出图质量 产出更高清 分
  • Firefly

    Firefly 流萤 中文对话式大语言模型在本文中 笔者将介绍关于Firefly 流萤 模型的工作 一个中文对话式大语言模型 https mp weixin qq com s TX7wj8IzD EaMTvk0bjRtA一个支持中文的176
  • View 的事件分发

    事件分发机制 1 1 事件分发的顺序 Activity gt ViewGroup gt View 1 2 事件分发涉及到的方法 public boolean dispatchTouchEvent MotionEvent ev 事件过来的时候
  • k8s 概念说明,k8s面试题

    什么是Kubernetes Kubernetes是一种开源容器编排系统 可自动化应用程序的部署 扩展和管理 Kubernetes 中的 Master 组件有哪些 Kubernetes 中的 Master 组件包括 API Server et
  • 4-ubuntu22.04-安装QT-5.15.2

    ubuntu22 04 安装QT 5 15 2 一 Ubuntu换源 二 命令行安装QT 5 15 2 三 配置环境变量 四 QT安装选择 五 QT环境依赖安装gcc和g 一 Ubuntu换源 换源注意根据自己系统的版本进行换源 有 bio
  • ElasticSearch适配器adapter的使用及配置

    文章目录 前言 一 修改启动器配置 application yml 二 适配器表映射文件 修改 conf es mytest user yml文件 单表映射索引示例sql 单表映射索引示例sql带函数或运算操作 多表映射 一对一 多对一 索
  • 计算机磁盘管理进行磁盘转移,将磁盘移到另一台计算机

    将磁盘移到另一台计算机 10 12 2017 本文内容 适用于 Windows 10 Windows 8 1 Windows Server 半年频道 Windows Server 2016 Windows Server 2012 R2 Wi
  • Hive 分组

    2 1 Group By 语句 GROUP BY 语句通常会和聚合函数一起使用 按照一个或者多个列队结果进行分组 然 后对每个组执行聚合操作 1 案例实操 1 计算 emp 表每个部门的平均工资 hive default gt select
  • 雪花算法(SnowFlake)

    简介 现在的服务基本是分布式 微服务形式的 而且大数据量也导致分库分表的产生 对于水平分表就需要保证表中 id 的全局唯一性 对于 MySQL 而言 一个表中的主键 id 一般使用自增的方式 但是如果进行水平分表之后 多个表中会生成重复的
  • Java线程的同步机制(synchronized关键字)

    线程的同步机制 synchronized 1 背景 例子 创建个窗口卖票 总票数为100张 使用实现Runnable接口的方式 1 问题 卖票过程中 出现了重票 错票 gt 出现了线程的安全问题 2 问题出现的原因 当某个线程操作车票的过程
  • spring中的扩展点解析以及实践使用

    文章目录 1 ApplicationContextInitializer 2 BeanDefinitionRegistryPostProcessor 3 BeanFactoryPostProcessor 4 InstantiationAwa
  • 西门子S7-200 PLC接地和接线

    对于所有的电器设备 接地和接线是非常重要的 它能够确保系统具备最优的操作特性 同时能够为系统提供更好的电子噪声保护 在接地和接线之前 必须先确保设备的电源已被切断 也要保证与该设备相关的设备电源已被切断 在对S7 200及其相关设备接线时
  • 从零推导一个多层感知机神经网络(附matlab源码,可直接运行)

    可以先跳到代码示例部分看看效果 算法基础 激活函数 损失函数 链式法则 向量求导 代码示例 代码文件结构说明 函数脚本 可运行脚本 效果演示 代码下载链接 算法基础 激活函数 激活函数的作用 激活函数把非线性引入了神经网络 后面的代码用到的
  • pnpm替换lerna+yarn的踩坑记录

    如果有使用monorepo的需求 lerna yarn会是很多开发者的选择 然而在实际开发中 lerna的很多功能我们并不需要 同时它也存在着一定的上手学习成本 而且 yarn也会存在一些问题比如多个项目会重复安装依赖 幽灵依赖等 这时候不
  • redis命令行基本操作

    文章目录 基本概念 对数据库的操作 对数据的操作 增删改查 数值操作 整数数据 浮点数据 其他 基本概念 redis的键是区分大小写的 user 与 USER 是两个键 配置文件 redis conf 对数据库的操作 SELECT
  • mpeg4视频中,I帧、p帧、B帧的判定

    mpeg4的每一帧开头是固定的 00 00 01 b6 那么我们如何判断当前帧属于什么帧呢 在接下来的2bit 将会告诉我们答案 注意 是2bit 不是byte 下面是各类型帧与2bit的对应关系 00 I Frame 01 P Frame
  • PBFT简单介绍

    PBFT是一种常用于联盟链的共识算法 中文名是实用拜占庭容错算法 首先用户发送交易到区块链网络中 主节点接收到交易并向其他节点进行广播 其他节点收到广播后记录下交易并广播给其他节点 当各节点收到相同交易的广播次数 包括节点自己本身一次 达到
  • windows10+python3.6+anaconda+pytorch-cpu的初步环境搭建

    windows10 python3 6 anaconda pytorch cpu的初步环境搭建 安装pytorch cpu 新建环境 1 利用anaconda进行创建新的环境 cmd conda create n pytorch pytho
  • 2018年LeetCode高频算法面试题刷题笔记——分割回文串(字符串)

    1 解答之前的碎碎念 这个题我的想法是 第一刀依次切在第1 s length 2个元素后面 得到两个字符串s0和s1 首先判断s0整体是否为回文 不是则第一刀的位置 1 然后再检测s1整体是否为回文 并在s1的第1 s1 length 2个