算法刷题心得:动态规划 scramble-string

2023-05-16

牛客网->在线编程->letcode->scramble-string

Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.Below is one possible representation ofs1 ="great":


To scramble the string, we may choose any non-leaf node and swap its two children.For example, if we choose the node"gr"and swap its two children, it produces a scrambled string"rgeat".


We say that"rgeat"is a scrambled string of"great".Similarly, if we continue to swap the children of nodes"eat"and"at", it produces a scrambled string"rgtae".


We say that"rgtae"is a scrambled string of"great".Given two stringss1 ands2 of the same length, determine if s2 is a scrambled string ofs1.


题目大意:将一个字符 Str1 串用二叉树表示(表示方式不唯一),若其某种表示方式的二叉树的左右子树经过任意交换可以变成另外一个字符串 Str2 ;则表示Str1和Str2是一对scramble-string。


刚开始拿到题目并没有用到DP,做了一个全局搜索,结果超时了。也先写一下我的思路,再贴一下参考别人的DP大神代码。我的思路:先用数字表示字符串,方便讲解,

定义:

1、切点,要将一个字符串变成两个非空二叉树,则需要将在字符串中间插空切下去,比如str1=“1234”就有12之间、23之间、34之间三个切点;后面根据切点的从左到右的顺序命名为:cut[i];

示例一:str1=“1234”、str2=“3142”;若想将str2经过变换成为str1,二叉树第一层分支点可以有三种切点情况;(判断可行情况是左右子树是否交叉,因为左右子树元素之间是不会交叉的,只是左右子树交换)


切点左子树右子树是否可行
cut[0]3142否(左子树范围[3]与右子树[1,4]范围交叉)
cut[1]3142(左子树范围[1,3]与右子树[2,4]范围交叉)
cut[2]3142(左子树范围[1,4]与右子树[2]范围交叉)

(其实已经构造出了最优子结构,动态规划的核心。但是由于对这种不是一维二维的动态规划见得少,没有做出来。。)我的代码就是这种深搜,最后超时。不知道代码有没有什么BUG,自己测了一些还没测出问题

map<char,vector<int> > tab,rtab;
map<char,int> flag;
string ss;
void clear(map<char,int> &tmp){
	map<char,int>::iterator it;
	for(it=tmp.begin(); it!=tmp.end(); it++)
		it->second = 0;
}
//功能:返回从左向右搜索,下一个可能切点的位置
//形参:s2是str2二叉树的某一个子树,left、right为在原str2的左右界限,pos为开始搜索位置
int c_find(const string &s2,int left,int right,int pos){
	if(pos>right)
		return right;
	int i=left, j=pos;
	clear(flag);
	do{
		int tmp;
		do{
			tmp = tab[s2[i-left]][flag[s2[i-left]]];
			if(tmp==-1 || tmp>=right)
				return right;
		}while(flag[s2[i-left]]++,tmp<left);
		j = max(j, tmp);
		flag[s2[i-left]]++;
	}while(i++<j);
	return --i;
}
//功能:返回从右向左搜索,下一个可能切点的位置
//形参:s2是str2二叉树的某一个子树,left、right为在原str2的左右界限,pos为开始搜索位置
int c_rfind(const string &s2,int left,int right,int pos){
	if(pos<left)
		return left;
	int i=left, j=pos;
	clear(flag);
	do{
		int tmp;
		do{
			tmp = rtab[s2[i-left]][flag[s2[i-left]]];
			if(tmp==-1 || tmp<=left)
				return left;
		}while(flag[s2[i-left]]++,tmp>right);
		j = min(j, tmp);
		//flag[s2[i-left]]++;
	}while(i++<(right-j));
	return j;
}
bool scramble_judge(const string &s1,const string &s2,int left,int right){
	//cout<<s2<<endl;
	if(left == right && ss[left]==s2[0])
		return true;
	if(right-left == 1){
		if((ss[left]==s2[0] && ss[right]==s2[1]) || (ss[left]==s2[1] && ss[right]==s2[0]))
			return true;
		else
			return false;
	}
	int tmp=-1,rtmp=0x3f3f3f3f;
	for(int i=left;i<right;i=min(tmp+1,left+right-rtmp+1)){
		tmp = c_find(s2, left, right, max(i,tmp+1));//左左右右查询
		/*if(tmp == right)
			return false;*/
		if(tmp<right && ( scramble_judge(s1,s2.substr(0,tmp-left+1),left,tmp) && scramble_judge(s1,s2.substr(tmp-left+1),tmp+1,right) ) ){
			return true;
		}else{
			rtmp = c_rfind(s2, left, right, min(rtmp-1,right+left-i));//左右左右查询
			if(rtmp <= left)
				return false;
			if( scramble_judge(s1,s2.substr(0,right-rtmp+1),rtmp,right) && scramble_judge(s1,s2.substr(right-rtmp+1),left,rtmp-1) )
				return true;
		}
	}
	return false;
}
bool isScramble(string s1, string s2) {
    int len1=s1.size(), len2=s2.size();
	if(len1 != len2)
		return false;
	if(0 == len1)
		return true;
	if(len1==1){
		return (s1[0] == s2[0]);
	}
	//下面到return建表是想优化一下下个切点位置;根据前面数字字符串那里讲解不能交叉的原理
	set<char> char_set; 
	for(int i=0; i<len1; i++){
		char_set.insert(s2[i]);
	}
	set<char>::iterator it;
	for(it=char_set.begin(); it!=char_set.end(); it++){
		flag[*it] = 0;
		tab[*it] = vector<int>(len1+1,-1);
		int j=0;
		for(int i=0; i<len1;i++){
			if(*it == s1[i])
				(tab[*it])[j++] = i;//str2某个字符在str1中出现的位置(存储顺序为递增)
		}
		if(j == 0)
			return false;
	}
	for(it=char_set.begin(); it!=char_set.end(); it++){
		rtab[*it] = vector<int>(len1+1,-1);
		int j=0,k=-1;
		while((tab[*it])[++k] != -1);
		while(k){
			(rtab[*it])[j++] = (tab[*it])[--k];//str2某个字符在str1中出现的位置(存储顺序为递减)
		}
	}
	return scramble_judge(s2, s2, 0, len1-1);
}




别人的动态规划算法:dp[k][i][j]表示str1从i开始长度为k,与str2从j开始长度为k的子串是否为scramble-string

bool isScramble(string s1, string s2) {
	int len1=s1.size(), len2=s2.size();
	if(len1 != len2)
		return false;
	//相当于 bool dp[len1][len1][len1];
	vector<vector<vector<bool> > > dp(len1, vector<vector<bool>>(len1,vector<bool>(len1,false)) );
	//初始化数组,子串长度为一时,只要相等就是
	for(int i=0; i<len1; i++){
		for(int j=0; j<len1; j++){
			if(s1[i] == s2[j])
				dp[0][i][j] = true;
		}
	}
	for(int k=1;k<len1; k++){
		for(int i=0; i<len1-k ;i++){
			for(int j=0; j<len1-k; j++){
				if(false == dp[k][i][j]){
					for(int q=0; q<k; q++){
						if( (dp[q][i][j] && dp[k-q-1][i+q+1][j+q+1]) || (dp[q][i][j+k-q] && dp[k-q-1][i+q+1][j]) )
							dp[k][i][j] = true;
					}
				}
			}
		}
	}
	return dp[len1-1][0][0];
}

  


  

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

算法刷题心得:动态规划 scramble-string 的相关文章

  • 关于驱动程序的可移植性

    差不多所有的linux内核设备驱动都可以运行在不止一种处理器上 这仅仅因为设备驱动作者遵循一些重要规则 这些规则包括使用合适的变量类型 xff0c 而不是依赖于特定内存页大小 xff0c 提防外部数据的大小端模式 xff0c 设立合适的数据
  • centos7 安装mysql详细流程

    工作中经常需要安装mysql xff0c 每次安装的时候 xff0c 总是用不同的方法安装 xff0c 有错误就解决一下 xff0c 今天又重新装了一次mysql xff0c 记录下过程 xff0c 以后就用这种方式安装了 xff01 1
  • 10000端口无法运行

    1 查询端口 netstat ano findstr 10000 2 查询端口名 tasklist findstr 1572 3 关闭端口 taskkill pid 1572 F
  • Cmake编译-CMAKE_C_COMPILER-NOTFOUND解决

    第一次写博客 xff0c 其实就是记录一下从零开始的学习之路上遇到的各种 bug xff0c 一方面为了防止忘了犯过的错误 xff08 比如下一次 xff09 xff1b 另一方面为了从错误中汲取经历 分析 bug 之前 xff0c 记录一
  • libcurl官方实例代码(HTTP,FTP,上传下载等等)

    http curl haxx se libcurl c example html Some of the Examples simple HTTP simple c shows how to get a remote web page in
  • stm32驱动NRF24L01_原理+代码解析

    目录 概念 废话篇 xff08 24L01简介 xff09 引脚分配 工作模式 通信地址理解 xff08 个人疑难点 xff09 原理分析 寄存器赏析 寄存器操作指令 配置寄存器 xff08 CONFIG xff0c 位置 xff1a 0X
  • CSS实现进度条和订单进度条

    由于近期需要做一个订单进度条 xff0c 比较直观的反应当前订单的状态 xff0c css样式借鉴了网上的相关代码 xff0c 下面是效果图 xff0c 以及实现说明 一 说明 1 首先页面需要引入jQuery的相关js 一般页面都已经引入
  • ROS中CANopen的使用(1)

    ROS中CANopen的使用 xff08 1 xff09 今天终于实现了通过ros来控制无人车 xff0c 心情非常激动 xff0c 先简要记录 工作环境 工控机使用的Ubuntu18 02 xff0c can卡采用的innodisk的UC
  • 组合导航在ROS中的解析(2)

    工作环境 ubuntu18 02 xff0c 组合导航使用网口接口 xff0c ros使用melodic实现过程 include lt ros ros h gt include lt stdio h gt include lt stdlib
  • 上位机与下位机进行交互

    一 上位机与下位机 xff08 1 xff09 什么是上位机 上位机是指可以直接发出操控命令的计算机 这里使用的是winfrom xff08 2 xff09 什么是下位机 下位机是指直接控制设备获取状况的计算机 xff0c 一般是PLC 单
  • alist无法访问文件 提示“failed get link ”这样修复

    阿里网盘挂载alist无法访问文件 xff0c 提示 failed get link invalid X Device Id xff1f 34 Failed get link invalid X Device Id 34 是挂载阿里云网盘到
  • STM32F4应用-串口通信

    STM32F4应用 串口通信 1 基本介绍1 1 简介1 2 串口协议1 3 通信过程 2 配置过程2 1 引脚复用2 2 配置步骤2 3 例子 参考文献 1 基本介绍 1 1 简介 串口通信涉及USART TX RX xff0c GND三
  • 使用ADB命令来停用、卸载荣耀20 PRO的系统应用

    今年双十一买了部荣耀20 Pro手机 xff0c 某天感觉某个系统应用 系统更新 贼烦人 xff0c 过段时间就提醒一次 xff1b 我就被逼着上网搜有没有思路 xff0c 然后就打开了罪恶的大门 个人博客 xff1a https blog
  • Python笔记【二】

    之前分享过一次我在学习Python的笔记 xff0c Python笔记 一 xff0c 最近有些新的收获 xff0c 分享一下 xff1b 个人博客 xff1a https blog csdn net zyooooxie random sa
  • Fiddler 使用命令行和Filters

    本文为博主原创 xff0c 未经许可严禁转载 本文链接 xff1a https blog csdn net zyooooxie article details 109020837 之前分享过一期 Fiddler断点 修改响应数据 xff0c
  • 代码改变生活-使用You-Get下载bilibili的视频【一】

    本文为博主原创 xff0c 未经许可严禁转载 本文链接 xff1a https blog csdn net zyooooxie article details 111307733 这篇分享是我在csdn的第100篇原创了 xff0c 真的是
  • Appium app自动化测试经验分享-find_element_by_android_uiautomator ()【二】

    本文为博主原创 xff0c 未经许可严禁转载 本文链接 xff1a https blog csdn net zyooooxie article details 113868447 之前分享过 find element by android
  • 数据完整性测试之【三】Redis缓存和数据库表里的记录

    本文为博主原创 xff0c 未经授权 xff0c 严禁转载及使用 本文链接 xff1a https blog csdn net zyooooxie article details 119377944 前面分享过 接口返回值 和 表记录 的校
  • Python笔记【十一】

    本文为博主原创 xff0c 未经授权 xff0c 严禁转载及使用 本文链接 xff1a https blog csdn net zyooooxie article details 123655926 继续学习Python xff0c 继续更
  • Python脚本之准备测试环境的用户数据

    本文为博主原创 xff0c 未经授权 xff0c 严禁转载及使用 本文链接 xff1a https blog csdn net zyooooxie article details 127645678 这期是讲述下 我准备测试环境用户数据的经

随机推荐

  • 1114Selenium web自动化测试经验分享-设置网页超时加载时间set_page_load_timeout()

    最开始学习web自动化测试就遇到一个小困扰 xff0c 有时候设计的用例可能会打开新浪 腾讯这些网站 xff0c 等待网页加载完成都要小半分钟 最近重拾web自动化测试 xff0c 又遇到这个困扰 个人博客 xff1a https blog
  • 1127UI自动化测试经验分享-显式等待(一)WebDriverWait类、until()方法

    最近忙于其他事情 xff0c 博客就没那么多时间来写 原本想先分享下三种等待方式 xff0c 但是隐式等待我还有点不太懂 这次先分享显式等待 个人博客 xff1a https blog csdn net zyooooxie 一 xff09
  • OpenCV框架介绍

    OpenCV框架介绍 概述 OpenCV是一个开放源代码的计算机视觉应用平台 xff0c 由英特尔公司下属研发中心俄罗斯团队发起该项目 xff0c 开源BSD证书 xff0c OpenCV的目标是实现实时计算机视觉 xff0c xff0c
  • 1128UI自动化测试经验分享-显式等待(二)expected_conditions模块、visibility_of_element_located(locator)

    expected conditions模块 提供的预期条件判断类 模块包含一套预定义的条件集合 xff0c 大大方便了 WebDriverWait 的使用 个人博客 xff1a https blog csdn net zyooooxie 一
  • Requests.request()方法分享【一】

    最近参加了一次新公司测试团队技术分享会 xff0c 有大佬分享了关于接口自动化框架 python 43 requests 43 ddt 43 unittest 43 jenkins xff0c 印象很深刻的是他的脚本测试用例的设计和requ
  • 指针 Swap交换函数

    64 努力的张张 的C 练习 数组 指针地址传递 Swap函数 首先 xff0c 我们先来看一下普通值传递和地址传递的区别 函数间普通值传递 上代码 xff1a span class token macro property span cl
  • 用两个栈实现一个队列【C语言】

    问题描述 xff1a 考虑用两个栈实现队列这样的特殊结构 问题分析 xff1a 我们靠两个栈实现队列 xff0c 肯定是一个用来存放入队的数据 xff0c 一个用来出栈 xff0c 在这里我们主要关注这个样几个问题 xff1a 什么时候队列
  • 数据库安全 --- 创建登录名 用户+配置权限【笔记】

    项目场景 xff1a 创建用户和给用户授权 解决方案 xff1a 1 创建用户 至此用户才创建成功 xff1a 2 配置权限 把查询Student表权限授给用户test xff1a 把对Student表和Course表的全部权限授予用户U2
  • Visual C++6.0 一些编译链接报错解决

    01 VC 43 43 编写图形化界面链接时出现 LIBCD lib crt0 obj error LNK2001 unresolved external symbol main 的解决方案 在我使用VC 43 43 编写一个图形化显示界面
  • lambda表达式【C++】

    lambda表达式 lambda表达式是C 43 43 11最重要也是最常用的一个特性 lambda来源于函数式编程的概念 优点 xff1a 声明式编程风格 xff1a 就地匿名定义目标函数或函数对象 xff0c 不需要额外写一个命名函数或
  • Qt学习笔记 day_03

    目录 十三 自定义代理类的实现1 基于QSpinBox的自定义代理类的实现2 自定义代理类的使用3 xff09 setItemDelegateForColumn 函数的使用注意 十三 自定义代理类的实现 1 基于QSpinBox的自定义代理
  • 版本控制软件SVN

    SVN学习 1 版本控制软件定义及用途 版本控制软件是为适应软件配置管理的需要 xff0c 控制软件的修改 xff0c 减少混乱 xff0c 提高软件生产效率 xff0c 其是软件质量保证的重要环节软件配置管理是对软件修改进行标识 组织和控
  • 螺旋桨的制作图文教程

    一 螺旋桨的一些基础概念 当我们把螺旋桨看成是一个一面旋转一面前进的机翼时 xff0c 就能借助已知的空气动力学常识 xff0c 直观地理解螺旋桨的基本工作原理 1 xff0e 桨距 动力桨距和几何桨距 桨距 xff1a 从广义而言 xff
  • 自制2.4G ELRS接收机,不需要打板,容易制作

    制作难度 xff1a 中等 xff0c 主要是器件太小 xff0c 焊接需要耐心 一 硬件材料 1 LoRa射频模块 xff0c sx1280 xff1a E28 2G4M12S 2 MCU Wifi模块 xff1a ESP 01F 3 各
  • Qt学习笔记 【C++】(4)

    目录 一 Qt中的C 43 43 11标准二 Explicit Linking 和 Implicit Linking三 自动生成的ui xxx ui文件四 常用快捷键 一 Qt中的C 43 43 11标准 Qt 5 中开启C 43 43 1
  • 串口发送接收字符串的C语言代码参考

    通过串口把字符串数据从单片机U1发送到单片机U2 xff0c 通过U2的LCD602显示出来 LCD602显示代码是用的一个比较不错的现成的显示代码 单片机串口传字符串 xff0c 主要是利用字符串的格式的特点 xff0c 在传输中结束串口
  • HTTP协议解析

    HTTP概述 HTTP 全称为 34 超文本传输协议 34 是一种应用非常广泛的应用层协议 我们平时打开一个网站 就是通过 HTTP 协议来传输数据的 HTTP工作过程 xff1a 当我们在浏览器中输入一个 34 网址 34 xff0c 此
  • 《算法导论》学习心得

    第四章 分治策略 xff08 1 xff09 Master Method中case 3中 正则条件 的含义 xff1a 保证f n 在每次递归后都比上一层小 xff08 非递增 xff09 否则显然T n gt f n xff08 2 xf
  • 《算法导论》 第11章部分答案

    注 xff1a 以下答案均为自己思考 xff0c 难免有误 xff0c 欢迎指正 11 3 1 xff1a 将长度为n的链表进行排序 xff0c 将关键值的散列值相同的元素排为相邻 而散列表有点类似于链接法解决冲突的散列表 11 3 2 x
  • 算法刷题心得:动态规划 scramble-string

    牛客网 gt 在线编程 gt letcode gt scramble string Given a string s1 we may represent it as a binary tree by partitioning it to t