2060. 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 boths1
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
ands2
consist of digits1-9
(inclusive), and lowercase English letters only.- The number of consecutive digits in
s1
ands2
does not exceed3
.
Solutions
Solution: Dynamic Programming
- Time complexity: O(n1*n2*1000)
- Space complexity: O(n1*n2*1000)
JavaScript
js
/**
* @param {string} s1
* @param {string} s2
* @return {boolean}
*/
const possiblyEquals = function (s1, s2) {
const n1 = s1.length;
const n2 = s2.length;
const dp = Array.from({ length: n1 + 1 }, () => {
return new Array(n2 + 1)
.fill('')
.map(() => new Map());
});
const isNumber = char => Number.isInteger(Number(char));
const findNextLetter = (s, index) => {
while (index < s.length && isNumber(s[index])) {
index += 1;
}
return index;
};
const getPaddings = num => {
const n = num.length;
const nums = [Number(num)];
if (n === 2) {
const [a, b] = num;
nums.push(Number(a) + Number(b));
}
if (n === 3) {
const [a, b, c] = num;
const num1 = Number(a) + Number(b) + Number(c);
const num2 = Number(a) + Number(`${b}${c}`);
const num3 = Number(`${a}${b}`) + Number(c);
nums.push(num1, num2, num3);
}
return nums;
};
const isPossiblyEncode = (a, b, padding) => {
if (a === n1 && b === n2) return padding === 0;
if (dp[a][b].has(padding)) return dp[a][b].get(padding);
if (a < n1 && isNumber(s1[a])) {
const index = findNextLetter(s1, a);
const nums = getPaddings(s1.slice(a, index));
for (const num of nums) {
if (isPossiblyEncode(index, b, padding + num)) {
dp[a][b].set(padding, true);
return true;
}
}
} else if (b < n2 && isNumber(s2[b])) {
const index = findNextLetter(s2, b);
const nums = getPaddings(s2.slice(b, index));
for (const num of nums) {
if (isPossiblyEncode(a, index, padding - num)) {
dp[a][b].set(padding, true);
return true;
}
}
} else if (padding < 0) {
if (a < n1 && isPossiblyEncode(a + 1, b, padding + 1)) {
dp[a][b].set(padding, true);
return true;
}
} else if (padding > 0) {
if (b < n2 && isPossiblyEncode(a, b + 1, padding - 1)) {
dp[a][b].set(padding, true);
return true;
}
} else if (a < n1 && b < n2 && s1[a] === s2[b] && isPossiblyEncode(a + 1, b + 1, 0)) {
dp[a][b].set(padding, true);
return true;
}
dp[a][b].set(padding, false);
return false;
};
return isPossiblyEncode(0, 0, 0);
};