LeetCode 2825: Make String a Subsequence Using Cyclic Increments (Two Pointers / Greedy)
LeetCode 2825Two PointersGreedyToday we solve LeetCode 2825 - Make String a Subsequence Using Cyclic Increments.
Source: https://leetcode.com/problems/make-string-a-subsequence-using-cyclic-increments/
English
Scan str1 left to right and greedily match the next needed char in str2. A character can match directly, or after one cyclic increment (for example, z -> a).
If we can advance pointer j through all of str2, answer is true. This is optimal because skipping a possible match never helps future matches.
Time O(n), space O(1).
class Solution {
public boolean canMakeSubsequence(String str1, String str2) {
int j = 0;
for (int i = 0; i < str1.length() && j < str2.length(); i++) {
char a = str1.charAt(i);
char b = str2.charAt(j);
char inc = (char) ((a - 'a' + 1) % 26 + 'a');
if (a == b || inc == b) j++;
}
return j == str2.length();
}
}func canMakeSubsequence(str1 string, str2 string) bool {
j := 0
for i := 0; i < len(str1) && j < len(str2); i++ {
a := str1[i]
b := str2[j]
inc := byte((int(a-'a')+1)%26 + 'a')
if a == b || inc == b {
j++
}
}
return j == len(str2)
}class Solution {
public:
bool canMakeSubsequence(string str1, string str2) {
int j = 0;
for (char a : str1) {
if (j == (int)str2.size()) break;
char b = str2[j];
char inc = char((a - 'a' + 1) % 26 + 'a');
if (a == b || inc == b) j++;
}
return j == (int)str2.size();
}
};class Solution:
def canMakeSubsequence(self, str1: str, str2: str) -> bool:
j = 0
for a in str1:
if j == len(str2):
break
b = str2[j]
inc = chr((ord(a) - ord('a') + 1) % 26 + ord('a'))
if a == b or inc == b:
j += 1
return j == len(str2)var canMakeSubsequence = function(str1, str2) {
let j = 0;
for (let i = 0; i < str1.length && j < str2.length; i++) {
const a = str1[i];
const b = str2[j];
const inc = String.fromCharCode((a.charCodeAt(0) - 97 + 1) % 26 + 97);
if (a === b || inc === b) j++;
}
return j === str2.length;
};中文
从左到右扫描 str1,贪心匹配 str2 当前需要的字符。每个字符可直接匹配,或做一次循环加一后匹配(例如 z -> a)。
若指针 j 能走完整个 str2,返回 true。这个贪心是正确的,因为能匹配却不匹配不会让后续更优。
时间复杂度 O(n),空间复杂度 O(1)。
class Solution {
public boolean canMakeSubsequence(String str1, String str2) {
int j = 0;
for (int i = 0; i < str1.length() && j < str2.length(); i++) {
char a = str1.charAt(i);
char b = str2.charAt(j);
char inc = (char) ((a - 'a' + 1) % 26 + 'a');
if (a == b || inc == b) j++;
}
return j == str2.length();
}
}func canMakeSubsequence(str1 string, str2 string) bool {
j := 0
for i := 0; i < len(str1) && j < len(str2); i++ {
a := str1[i]
b := str2[j]
inc := byte((int(a-'a')+1)%26 + 'a')
if a == b || inc == b {
j++
}
}
return j == len(str2)
}class Solution {
public:
bool canMakeSubsequence(string str1, string str2) {
int j = 0;
for (char a : str1) {
if (j == (int)str2.size()) break;
char b = str2[j];
char inc = char((a - 'a' + 1) % 26 + 'a');
if (a == b || inc == b) j++;
}
return j == (int)str2.size();
}
};class Solution:
def canMakeSubsequence(self, str1: str, str2: str) -> bool:
j = 0
for a in str1:
if j == len(str2):
break
b = str2[j]
inc = chr((ord(a) - ord('a') + 1) % 26 + ord('a'))
if a == b or inc == b:
j += 1
return j == len(str2)var canMakeSubsequence = function(str1, str2) {
let j = 0;
for (let i = 0; i < str1.length && j < str2.length; i++) {
const a = str1[i];
const b = str2[j];
const inc = String.fromCharCode((a.charCodeAt(0) - 97 + 1) % 26 + 97);
if (a === b || inc === b) j++;
}
return j === str2.length;
};
Comments