Skip to content

Latest commit

 

History

History
25 lines (15 loc) · 2.22 KB

File metadata and controls

25 lines (15 loc) · 2.22 KB

2060.Check-if-an-Original-String-Exists-Given-Two-Encoded-Strings

我们来看一个简单的例子。假设s1="3b3c", s2="2b3",那么我们会怎么判定两个字符串是否可能等效?

第一步,我们发现s1开头有三个待定,s2开头有两个待定,所以显然我们可以消去两个。所以转化为 s1="1b3c", s2="b3"

第二步,我们发现s1开头有一个待定,但s2开头是确定的字母,所以显然我们会将s1开头的待定匹配给s2开头的那个b。所以转化为 s1="b3c", s2="b3"

第三步,我们发现s1开头是b,s2开头是b,二者恰好匹配可以共同消去。所以转化为 s1="3c", s2="3"

第四步,类似地我们对消两者开头的三个待定。所以转化为 s1="c", s2=""

最终,s2已经考察完,但是s1还有一个字符。所以匹配失败。

综上,我们发现,如果所有的待定的数目都是固定的,那么本题的本质就是一步步消减两个字符串开头能匹配的部分,然后递归处理后续。本题增加的难点其实就是针对数字串的处理,例如"123a",那么针对“123”的拆解,其实对应的可能其实是六种可能“123a”,“15a”,“24a”,“6a”。我们只要挨个将他们递归处理就行啦。

所以本题的递归函数可以设计为bool dfs(vector<string>&t1, int i, int num1, vector<string>&t2, int j, int num2). 其中t1是将原s1按数字/字母进行拆解后的字符串数组,例如"s1=23ab111c",那么t就是{23,a,b,111,c}. i表示在t1数组里我们当前处理第几项。num1表示在处理当前项之前手头还有多少个“待定”可以用。t2,j,num2同理定义。

我们的算法步骤是:

  1. 无论对于t1还是t2,如果当前项是一个数字,那么我们拆解这个数字(分为四种可能)并叠加到当前的num上去,直至当前项是字母为止。
  2. 如果num1和num2都不为零,我们必然对消直至其中一个变为0
  3. 如果num1和num2只有一个为零,那么说明一方的字母可以匹配另一方的待定。
  4. 如果num1和num2都为零,说明我们必须比较两个字母。如果匹配就继续,否则就返回false
  5. 只有t1和t2都恰好对消完全(包括待定),才能说明二者匹配。