Skip to main content

Longest Palindromic Subsequence After at Most K Operations - Solution & Explanation

MediumStringDynamic Programming10 min readAsked at: Google
Practice this problem

Problem Statement

You are given a string s and an integer k.

In one operation, you can replace the character at any position with the next or previous letter in the alphabet (wrapping around so that 'a' is after 'z'). For example, replacing 'a' with the next letter results in 'b', and replacing 'a' with the previous letter results in 'z'. Similarly, replacing 'z' with the next letter results in 'a', and replacing 'z' with the previous letter results in 'y'.

Return the length of the longest palindromic subsequence of s that can be obtained after performing at most k operations.

 

Example 1:

Input: s = "abced", k = 2

Output: 3

Explanation:

  • Replace s[1] with the next letter, and s becomes "acced".
  • Replace s[4] with the previous letter, and s becomes "accec".

The subsequence "ccc" forms a palindrome of length 3, which is the maximum.

Example 2:

Input: s = "aaazzz", k = 4

Output: 6

Explanation:

  • Replace s[0] with the previous letter, and s becomes "zaazzz".
  • Replace s[4] with the next letter, and s becomes "zaazaz".
  • Replace s[3] with the next letter, and s becomes "zaaaaz".

The entire string forms a palindrome of length 6.

 

Constraints:

  • 1 <= s.length <= 200
  • 1 <= k <= 200
  • s consists of only lowercase English letters.

Approach Overview

Problem Overview: You are given a string s and an integer k. You may perform at most k character modification operations. Each operation changes a character toward another letter with a circular alphabet cost. The goal is to compute the maximum length of a palindromic subsequence that can be formed after spending at most k total cost.

The challenge combines classic string subsequence reasoning with a constrained operation budget. You must decide whether to match characters at both ends of a substring or skip them, while tracking how many operations remain.

Approach 1: Brute Force Recursion (Exponential Time)

The naive idea explores every subsequence while trying to match characters from both ends. For indices i and j, either skip the left character, skip the right character, or try converting them to match if the cost fits within the remaining budget. This produces a recursive branching tree where each state represents (i, j, remainingOps). Without caching, many identical subproblems repeat, leading to exponential time complexity O(3^n) in the worst case and recursion depth O(n) space. This approach mainly helps understand the decision process but is impractical for real constraints.

Approach 2: Memoized Search / Top‑Down Dynamic Programming (O(n^2 * k))

The optimal strategy uses dynamic programming with memoization. Define a recursive function dfs(i, j, rem) that returns the longest palindromic subsequence length within substring s[i..j] when rem operations remain. If characters already match, include both ends and continue with dfs(i+1, j-1, rem). If they differ, compute the circular alphabet cost to transform them into the same character; if that cost ≤ rem, match them and recurse with reduced operations.

You also consider skipping characters: dfs(i+1, j, rem) or dfs(i, j-1, rem). Memoization stores results for every (i, j, rem) state, eliminating repeated computation. The number of states is O(n^2 * k), and each state performs constant work, producing O(n^2 * k) time complexity and O(n^2 * k) space for the cache. This technique is a standard pattern in constrained subsequence problems that combine string processing with dynamic programming.

Recommended for interviews: Interviewers expect the memoized search or equivalent DP formulation. Starting with the recursive idea shows you understand subsequence choices (match or skip). Adding memoization demonstrates optimization skills and knowledge of overlapping subproblems, which is the key insight behind the O(n^2 * k) solution.

Solution

We design a function dfs(i, j, k), which represents the length of the longest palindromic subsequence that can be obtained in the substring s[i..j] with at most k operations. The answer is dfs(0, n - 1, k).

The calculation process of the function dfs(i, j, k) is as follows:

  • If i > j, return 0;
  • If i = j, return 1;
  • Otherwise, we can ignore s[i] or s[j] and calculate dfs(i + 1, j, k) and dfs(i, j - 1, k) respectively; or we can change s[i] and s[j] to the same character and calculate dfs(i + 1, j - 1, k - t) + 2, where t is the ASCII code difference between s[i] and s[j].
  • Return the maximum value of the above three cases.

To avoid repeated calculations, we use memoized search.

The time complexity is O(n^2 times k), and the space complexity is O(n^2 times k). Where n is the length of the string s.

Code

Python

Java

C++

Go

TypeScript

Try this approach in the editor →

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Brute Force RecursionO(3^n)O(n)Conceptual understanding of subsequence decisions before optimization
Memoized Search (Top-Down DP)O(n^2 * k)O(n^2 * k)General case and interview solution when operations are limited by k

Video Solution

3472. Longest Palindromic Subsequence After at Most K Operations | DP | Cyclic BehaviourAryan Mittal2,953 views views

Watch 6 more video solutions →

Frequently Asked Questions

Is Longest Palindromic Subsequence After at Most K Operations easy or hard?
The problem is generally rated Medium. The base idea resembles the classic longest palindromic subsequence DP, but the added constraint of at most k operations introduces an additional state dimension, increasing both reasoning complexity and implementation detail.
Longest Palindromic Subsequence After at Most K Operations Python/Java solution
Python and Java implementations typically use recursive DFS with a memoization cache such as functools.lru_cache in Python or a HashMap/3D array in Java. The algorithm tracks (left index, right index, remaining operations) and computes the best palindrome length in O(n^2 * k) time.
How to solve Longest Palindromic Subsequence After at Most K Operations in O(n^2 * k)?
Use top‑down DP with memoization. Recursively evaluate dfs(i, j, remainingOps) and cache results. If characters match or can be converted within the remaining cost, include them in the palindrome and move inward; otherwise try skipping one side. Memoization ensures each (i, j, k) state is computed once.
What is the best approach for Longest Palindromic Subsequence After at Most K Operations?
The best approach uses memoized search (top‑down dynamic programming). Define a DP state (i, j, k) representing the longest palindromic subsequence inside substring s[i..j] with k operations remaining. At each step you either match the characters (spending the required cost) or skip one side. This reduces repeated work and runs in O(n^2 * k) time.
Is Longest Palindromic Subsequence After at Most K Operations asked at Google/Amazon/Meta?
Palindrome subsequence problems and constrained dynamic programming variants frequently appear in interviews at companies like Google, Amazon, and Meta. While this exact numbered problem may vary, the pattern of DP on substrings with extra constraints is a common interview topic.
What data structure is used in Longest Palindromic Subsequence After at Most K Operations?
The solution primarily uses dynamic programming with memoization. A 3D DP cache or hash map stores results for states defined by substring indices and remaining operations (i, j, k). Recursion or a top‑down DFS drives the state transitions.
What is the time complexity of Longest Palindromic Subsequence After at Most K Operations?
The optimized dynamic programming solution runs in O(n^2 * k) time. There are O(n^2) possible substring pairs (i, j) and up to k remaining operation states. Each state performs constant transitions such as matching characters or skipping one index.

Ready to solve this problem?

Practice Longest Palindromic Subsequence After at Most K Operations with our built-in code editor and test cases.

Practice on FleetCode