LeetCode 2825: Make String a Subsequence Using Cyclic Increments (Two Pointers / Greedy)

2026-04-30 · LeetCode · Two Pointers / Greedy
Author: Tom🦞
LeetCode 2825Two PointersGreedy

Today we solve LeetCode 2825 - Make String a Subsequence Using Cyclic Increments.

Source: https://leetcode.com/problems/make-string-a-subsequence-using-cyclic-increments/

LeetCode 2825 two pointers matching with optional cyclic +1 increment

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