首页 > 其他分享 >LeetCode 2060. Check if an Original String Exists Given Two Encoded Strings

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

时间:2024-05-07 12:44:17浏览次数:27  
标签:Given String Exists s2 s1 l2 l1 diff memo

原题链接在这里:https://leetcode.com/problems/check-if-an-original-string-exists-given-two-encoded-strings/description/

题目:

An original string, consisting of lowercase English letters, can be encoded by the following steps:

  • Arbitrarily split it into a sequence of some number of non-empty substrings.
  • Arbitrarily choose some elements (possibly none) of the sequence, and replace each with its length (as a numeric string).
  • Concatenate the sequence as the encoded string.

For example, one way to encode an original string "abcdefghijklmnop" might be:

  • Split it as a sequence: ["ab", "cdefghijklmn", "o", "p"].
  • Choose the second and third elements to be replaced by their lengths, respectively. The sequence becomes ["ab", "12", "1", "p"].
  • Concatenate the elements of the sequence to get the encoded string: "ab121p".

Given two encoded strings s1 and s2, consisting of lowercase English letters and digits 1-9 (inclusive), return true if there exists an original string that could be encoded as both s1 and s2. Otherwise, return false.

Note: The test cases are generated such that the number of consecutive digits in s1 and s2 does not exceed 3.

Example 1:

Input: s1 = "internationalization", s2 = "i18n"
Output: true
Explanation: It is possible that "internationalization" was the original string.
- "internationalization" 
  -> Split:       ["internationalization"]
  -> Do not replace any element
  -> Concatenate:  "internationalization", which is s1.
- "internationalization"
  -> Split:       ["i", "nternationalizatio", "n"]
  -> Replace:     ["i", "18",                 "n"]
  -> Concatenate:  "i18n", which is s2

Example 2:

Input: s1 = "l123e", s2 = "44"
Output: true
Explanation: It is possible that "leetcode" was the original string.
- "leetcode" 
  -> Split:      ["l", "e", "et", "cod", "e"]
  -> Replace:    ["l", "1", "2",  "3",   "e"]
  -> Concatenate: "l123e", which is s1.
- "leetcode" 
  -> Split:      ["leet", "code"]
  -> Replace:    ["4",    "4"]
  -> Concatenate: "44", which is s2.

Example 3:

Input: s1 = "a5b", s2 = "c5b"
Output: false
Explanation: It is impossible.
- The original string encoded as s1 must start with the letter 'a'.
- The original string encoded as s2 must start with the letter 'c'.

Constraints:

  • 1 <= s1.length, s2.length <= 40
  • s1 and s2 consist of digits 1-9 (inclusive), and lowercase English letters only.
  • The number of consecutive digits in s1 and s2 does not exceed 3.

题解:

Use DFS + memo. memo[i][j][diff] means s1 up to i and s2 up to j with diff count are equal.

The diff is number difference. Say s1 is "5i", s2 is "2a", the first char of s1 is 5 and first char of s2 is 2, diff is 3.

DFS state needs current i, j index, current diff, char array of s1 and s2 and memo.

When both i, j hit the end, check if diff is equal to 0.

To cut the branches, if we calculate the value before, return the memo directly.

If current char of s1 is letter, move to the next one of s1 with diff - 1.

Vice versa, if current char of s2 is letter, move to next one of s2 with diff + 1.

If current char of s1 is digit, calculate the value and move diff - val.

Vice versa for s2.

Time Complexity: exponential. 

Space: O(l1 * l2 * 2000). l1 = s1.length(). l2 = s2.length().

AC Java:

 1 class Solution {
 2     public boolean possiblyEquals(String s1, String s2) {
 3         int l1 = s1.length();
 4         int l2 = s2.length();
 5         Boolean [][][] memo = new Boolean[l1 + 1][l2 + 1][2000];
 6         return dfs(0, 0, 0, l1, l2, s1.toCharArray(), s2.toCharArray(), memo);
 7     }
 8 
 9     private boolean dfs(int i, int j, int diff, int l1, int l2, char[] s1, char[] s2, Boolean[][][] memo){
10         if(i == l1 && j == l2){
11             return diff == 0;
12         }
13 
14         if(memo[i][j][diff + 1000] != null){
15             return memo[i][j][diff + 1000];
16         }
17 
18         if(i < l1 && j < l2 && diff == 0 && s1[i] == s2[j]){
19             if(dfs(i + 1, j + 1, diff, l1, l2, s1, s2, memo)){
20                 return memo[i][j][diff + 1000] = true;
21             }
22         }
23 
24         // If s1[i] is a letter
25         if(i < l1 && Character.isLetter(s1[i]) && diff > 0 && dfs(i + 1, j, diff - 1, l1, l2, s1, s2, memo)){
26             return memo[i + 1][j][diff + 1000] = true;
27         }
28 
29         // If s2[j] is a letter
30         if(j < l2 && Character.isLetter(s2[j]) && diff < 0 && dfs(i, j + 1, diff + 1, l1, l2, s1, s2, memo)){
31             return memo[i][j + 1][diff + 1000] = true;
32         }
33 
34         for(int k = i, val = 0; k < l1 && Character.isDigit(s1[k]); k++){
35             val = val * 10 + (int)(s1[k] - '0');
36             if(dfs(k + 1, j, diff - val, l1, l2, s1, s2, memo)){
37                 return memo[k + 1][j][diff + 1000] = true;
38             }
39         }
40 
41         for(int k = j, val = 0; k < l2 && Character.isDigit(s2[k]); k++){
42             val = val * 10 + (int)(s2[k] - '0');
43             if(dfs(i, k + 1, diff + val, l1, l2, s1, s2, memo)){
44                 return memo[i][k + 1][diff + 1000] = true;
45             }
46         }
47 
48         return memo[i][j][diff + 1000] = false;
49     }
50 }

类似Wildcard Matching.

标签:Given,String,Exists,s2,s1,l2,l1,diff,memo
From: https://www.cnblogs.com/Dylan-Java-NYC/p/18177019

相关文章

  • Js中valueOf和toString区别和使用
    对于number、string、Boolean、object、symbol数据类型调用valueOf方法,得到的都是数据本身(null、undefined两种类型上的原型链上没有valueOf方法)点击查看代码vara=1;varaa=a.valueOf();console.log(aa==a);//truevarb='a';......
  • 顺序栈实现进制转换 和 通过键盘输入一个包括 '(' 和 ')' 的字符串string ,判断字符串
    /********************************************************************************************************** filename: Zqh_栈实现.c* author : [email protected]* date : 2024/05/05* function: 顺序栈实现进制转换和通过键盘输入一个包括'('和')'......
  • ABC240Ex Sequence of Substrings
    ABC240ExSequenceofSubstringsLIS的好题改编。约定\(S(l,r)\)为字符串\(s\)中第\(l\)位到底\(r\)​位。\(S(l,r)<S(x,y)\)为字符串中\([l,r]\)的子串字典序比\([x,y]\)的子串小。前置LIS的\(n\logn\)求法。题解我们考虑按照类似于朴素LIS的方式设状......
  • C# String.Split 将字符串按照指定的分隔符分割成一个字符串数组
    以下两种方式都可以分割字符串string[]arr=s.Split('\n');string[]arr=s.Split(newchar[]{'\n'},StringSplitOptions.RemoveEmptyEntries);区别:string[]arr=s.Split('\n');:这种方式使用单个字符作为分隔符,将字符串s按照换行符('\n')进行分割。但是,此......
  • WPF Text MultiBinding StringFormat
    <TextBlock.Text><MultiBindingStringFormat="R:{0:N0},G:{1:N0},B:{2:N0}"><BindingPath="Value"ElementName="_red"/><BindingPath="Value"ElementName="_green"/>......
  • SystemVerilog -- 2.3 Data Types ~ SystemVerilog Strings
    SystemVerilogStringsWhatisaSystemVerilogstring?SyntaxSystemVerilogStringExampleHowarestringsrepresentedinVerilog?StringOperatorsExampleBasicStringMethodsExampleStringConversionMethodsstr.atoi()......
  • C++中StringPiece了解
    转自:https://blog.csdn.net/zxpoiu/article/details/1172580471.介绍使用c++string类不可避免会带来很多不必要的拷贝,拷贝多了必然影响性能。因此在很多高性能C++框架的实现中,都会使用StringPiece类作为string类的wrapper,该类只持有目标字符串的指针,而避免额外的拷贝。class......
  • string类
    string类文档与其他的标准库类型一样,想要使用string类型,必须包含相关的头文件。且string类是位于std命名空间中的。但在实际的项目中,最好避免在头文件中使用usingnamespacestd;,因为这样会引入整个std命名空间,可能会导致命名冲突。#include<string>usingnamespacestd;常......
  • golang strings.Join的用法
    在Go语言中,strings.Join函数用于将一个字符串切片([]string)连接成一个单独的字符串,并且可以在它们之间插入一个指定的分隔符。这个函数是strings包中的一部分,因此在使用之前需要先导入这个包。以下是strings.Join函数的基本用法:packagemainimport("fmt""stri......
  • ABC347B Substring
    题目描述给你一个由小写英文字母组成的字符串S,S有多少个不同的非空子串?子串是连续的子序列。例如,xxx是yxxxy的子串,但不是xxyxx的子串。数据范围:S是长度在1和100之间(含)的字符串,由小写英文字母组成。题解我认为这道题放在普及组的话,非常适合放在第一题和第二题之间,......