How to print maximum number of A’s using given four keys
Last Updated : 24 Apr, 2025
This is a famous interview question asked in Google and many other company interviews. Below is the problem statement.
Imagine you have a special keyboard with the following keys:
Key 1: Prints ‘A’ on screen
Key 2: (Ctrl-A): Select screen
Key 3: (Ctrl-C): Copy selection to buffer
Key 4: (Ctrl-V): Print buffer on screen appending it after what has already been printed.
If you can only press the keyboard for n times (with the above four keys), write a program to produce maximum numbers of A’s on the screen.
Examples:
Input: n = 3
Output: 3
Explanation: Press key 1 three times.
Input: n = 7
Output: 9
Explanation: The best key sequence is key 1, key 1, key 1, key 2, key 3, key4, key 4.
Below are few important points to note.
a) For n < 7, the output is n itself.
b) Ctrl V can be used multiple times to print current buffer. The idea is to compute the optimal string length for n keystrokes by using a simple insight. The sequence of n keystrokes which produces an optimal string length will end with a suffix of Ctrl-A, a Ctrl-C, followed by only Ctrl-V’s . (For n > 6)
[Naive Approach] Using Recursion – O(2 ^ n) time and O(n) space
- The task is to find out the breakpoint after which we get the above suffix of keystrokes.
Definition of a breakpoint is that instance after which we need to only press Ctrl-A, Ctrl-C once and then only Ctrl-V’s afterward to generate the optimal length. - If we loop from n-3 to 1 and choose each of these values for the break-point, and compute that optimal string they would produce.
- Once the loop ends, we will have the maximum of the optimal lengths for various breakpoints, thereby giving us the optimal length for n keystrokes.
C++ #include <iostream> using namespace std; int optimalKeys(int n) { // The optimal string length is n when n is smaller than 7 if (n <= 6) return n; // Initialize result int max = 0; // Try all possible break-points 'b' after which we // will have Ctrl-A, Ctrl-C and then only Ctrl-V all the way. for (int b = n - 3; b >= 1; b--) { // If the breakpoint is b at b'th keystroke then the optimal // string would have length (n-b-1) * optimalKeys(b); int curr = (n - b - 1) * optimalKeys(b); if (curr > max) max = curr; } return max; } int main() { int n = 7; cout << optimalKeys(n) << endl; }
Java class GfG { static int optimalKeys(int n) { // The optimal string length is n when n is smaller than 7 if (n <= 6) return n; // Initialize result int max = 0; // Try all possible break-points 'b' after which we // will have Ctrl-A, Ctrl-C and then only Ctrl-V all the way. for (int b = n - 3; b >= 1; b--) { // If the breakpoint is b at b'th keystroke then the optimal // string would have length (n - b - 1) * optimalKeys(b); int curr = (n - b - 1) * optimalKeys(b); if (curr > max) max = curr; } return max; } public static void main(String[] args) { int n = 7; System.out.println(optimalKeys(n)); } }
Python def optimalKeys(n): # The optimal string length is n when n is smaller than 7 if n <= 6: return n # Initialize result max_val = 0 # Try all possible break-points 'b' after which we # will have Ctrl-A, Ctrl-C and then only Ctrl-V all the way. for b in range(n - 3, 0, -1): # If the breakpoint is b at b'th keystroke then the optimal # string would have length (n - b - 1) * optimalKeys(b); curr = (n - b - 1) * optimalKeys(b) if curr > max_val: max_val = curr return max_val if __name__ == "__main__": n = 7 print(optimalKeys(n))
C# using System; class GfG { static int optimalKeys(int n) { // The optimal string length is n when n is smaller than 7 if (n <= 6) return n; // Initialize result int max = 0; // Try all possible break-points 'b' after which we // will have Ctrl-A, Ctrl-C and then only Ctrl-V all the way. for (int b = n - 3; b >= 1; b--) { // If the breakpoint is b at b'th keystroke then the // optimal string would have length (n - b - 1) * optimalKeys(b); int curr = (n - b - 1) * optimalKeys(b); if (curr > max) max = curr; } return max; } static void Main() { int n = 7; Console.WriteLine(optimalKeys(n)); } }
JavaScript function optimalKeys(n) { // The optimal string length is n // when n is smaller than 7 if (n <= 6) return n; // Initialize result let max = 0; // Try all possible break-points 'b' after which we // will have Ctrl-A, Ctrl-C and then only Ctrl-V all the way. for(let b = n - 3; b >= 1; b--) { // If the breakpoint is b at b'th keystroke then the optimal // string would have length (n - b - 1) * optimalKeys(b); let curr = (n - b - 1) * optimalKeys(b); if (curr > max) max = curr; } return max; } let n = 7; console.log(optimalKeys(n));
[Better Approach] Using Dynamic Programming – O(n ^ 2) time and O(n) space
Below is a Dynamic Programming-based implementation where an auxiliary array screen[n]
is used to store the results of subproblems. By solving smaller subproblems first and building upon them, the approach efficiently calculates the maximum number of ‘A’s for larger inputs, ensuring an scalable solution.
C++ #include <iostream> using namespace std; int optimalKeys(int n) { // The optimal string length is n when n is // smaller than 7 if (n <= 6) return n; int screen[n]; // Initializing the optimal lengths array // for until 6 input strokes for (int i = 1; i <= 6; i++) screen[i - 1] = i; // Solve all subproblems in bottom manner for (int i = 7; i <= n; i++) { screen[i - 1] = 0; // For any keystroke n, we need to loop from n-3 keystrokes // back to 1 keystroke to find a breakpoint 'b' after which we // will have ctrl-a, ctrl-c and then only ctrl-v all the way. for (int b = i - 3; b >= 1; b--) { // If the breakpoint is at b'th keystroke then // the optimal string would have length // (i - b - 1) * screen[b - 1]; int curr = (i - b - 1) * screen[b - 1]; if (curr > screen[i - 1]) screen[i - 1] = curr; } } return screen[n - 1]; } int main() { int n = 7; cout << optimalKeys(n) << endl; return 0; }
Java import java.io.*; class GfG { static int optimalKeys(int n) { // The optimal string length is n // when n is smaller than 7 if (n <= 6) return n; int screen[] = new int[n]; // Initializing the optimal lengths // array for until 6 input strokes for (int i = 1; i <= 6; i++) screen[i - 1] = i; // Solve all subproblems in bottom manner for (int i = 7; i <= n; i++) { // Initialize length of optimal // string for n keystrokes screen[i - 1] = 0; // For any keystroke n, we need // to loop from n-3 keystrokes // back to 1 keystroke to find // a breakpoint 'b' after which we // will have ctrl-a, ctrl-c and // then only ctrl-v all the way. for (int b = i - 3; b >= 1; b--) { // if the breakpoint is at b'th // keystroke then the optimal string // would have length (i-b-1)*screen[b-1]; int curr = (i - b - 1) * screen[b - 1]; if (curr > screen[i - 1]) screen[i - 1] = curr; } } return screen[n - 1]; } public static void main(String[] args) { int n = 7; System.out.println(optimalKeys(n)); } }
Python def optimalKeys(n): # The optimal string length is # n when n is smaller than 7 if (n <= 6): return n screen = [0] * n # Initializing the optimal lengths # array for until 6 input strokes. for i in range(1, 7): screen[i - 1] = i # Solve all subproblems in bottom manner for i in range(7, n + 1): # Initialize length of optimal # string for n keystrokes screen[i - 1] = 0 # For any keystroke n, we need to loop from # n-3 keystrokes back to 1 keystroke to find a # breakpoint 'b' after which we will have ctrl-a, # ctrl-c and then only ctrl-v all the way. for b in range(i - 3, 0, -1): # if the breakpoint is at b'th keystroke then # the optimal string would have length # (i-b-1)*screen[b-1]; curr = (i - b - 1) * screen[b - 1] if (curr > screen[i - 1]): screen[i - 1] = curr return screen[n - 1] if __name__ == "__main__": n = 7 print(optimalKeys(n))
C# using System; class GfG { static int optimalKeys(int n) { // The optimal string length is n when n is smaller // than 7 if (n <= 6) return n; int[] screen = new int[n]; // Initialize the optimal lengths array for up to 6 // keystrokes for (int i = 1; i <= 6; i++) screen[i - 1] = i; // Solve all subproblems in a bottom-up manner for (int i = 7; i <= n; i++) { // Initialize length of the optimal string for n // keystrokes screen[i - 1] = 0; // For any keystroke n, loop from n-3 keystrokes // back to 1 keystroke to find a breakpoint 'b' // after which we will have Ctrl-A, Ctrl-C, and // then only Ctrl-V all the way. for (int b = i - 3; b >= 1; b--) { // If the breakpoint is at b'th keystroke, // the optimal string would have length (i - // b - 1) * screen[b - 1]; int curr = (i - b - 1) * screen[b - 1]; if (curr > screen[i - 1]) screen[i - 1] = curr; } } return screen[n - 1]; } static void Main(string[] args) { int n = 7; Console.WriteLine(optimalKeys(n)); } }
JavaScript function optimalKeys(n) { // The optimal string length is n when n is smaller than 7 if (n <= 6) return n; let screen = new Array(n); for (let i = 0; i < n; i++) { screen[i] = 0; } // Initializing the optimal lengths // array for until 6 input strokes for (let i = 1; i <= 6; i++) screen[i - 1] = i; // Solve all subproblems in bottom manner for (let i = 7; i <= n; i++) { // Initialize length of optimal string for n keystrokes screen[i - 1] = 0; // For any keystroke n, we need to loop from // n-3 keystrokes back to 1 keystroke to find // a breakpoint 'b' after which we will have // ctrl-a, ctrl-c and then only ctrl-v all the way. for (let b = i - 3; b >= 1; b--) { // If the breakpoint is at b'th keystroke then // the optimal string would have length // (i-b-1)*screen[b-1]; let curr = (i - b - 1) * screen[b - 1]; if (curr > screen[i - 1]) screen[i - 1] = curr; } } return screen[n - 1]; } let n = 7; console.log(optimalKeys(n));
[Expected Approach] Using Dynamic Programming (Optimized) – O(n) time and O(n) space
As the number of A’s increases, the benefit of pressing Ctrl-V more than three times becomes negligible compared to simply starting the sequence of Ctrl-A, Ctrl-C, and Ctrl-V again. Therefore, the above approach can be optimized by limiting the check to pressing Ctrl-V only 1, 2, or 3 times.
C++ #include <iostream> using namespace std; int optimalKeys(int n) { // The optimal string length is n when n is smaller than 7 if (n <= 6) return n; // An array to store result of subproblems int screen[n]; // Initialize the optimal lengths array for up to 6 keystrokes for (int i = 1; i <= 6; i++) screen[i - 1] = i; // Solve all subproblems in a bottom-up manner for (int i = 7; i <= n; i++) { // For any keystroke n, calculate the maximum of: // 1. Pressing Ctrl-V once after copying the A's // obtained by (n-3) keystrokes. // 2. Pressing Ctrl-V twice after copying the A's // obtained by (n-4) keystrokes. // 3. Pressing Ctrl-V thrice after copying the A's // obtained by (n-5) keystrokes. screen[i - 1] = max(2 * screen[i - 4], max(3 * screen[i - 5], 4 * screen[i - 6])); } return screen[n - 1]; } int main() { int n = 7; cout << optimalKeys(n) << endl; return 0; }
Java class GfG { static int optimalKeys(int n) { // The optimal string length is n when n is smaller than 7 if (n <= 6) return n; // An array to store result of subproblems int[] screen = new int[n]; // Initializing the optimal lengths array for // until 6 input strokes for (int i = 1; i <= 6; i++) screen[i - 1] = i; // Solve all subproblems in bottom-up manner for (int i = 7; i <= n; i++) { // for any keystroke n, we will need to choose between: // 1. pressing Ctrl-V once after copying the // A's obtained by n-3 keystrokes. // 2. pressing Ctrl-V twice after copying the A's // obtained by n-4 keystrokes. // 3. pressing Ctrl-V thrice after copying the A's // obtained by n-5 keystrokes. screen[i - 1] = Math.max(2 * screen[i - 4], Math.max(3 * screen[i - 5], 4 * screen[i - 6])); } return screen[n - 1]; } public static void main(String[] args) { int n = 7; System.out.println(optimalKeys(n)); } }
Python def optimalKeys(n): # The optimal string length is n when n is smaller than 7 if n <= 6: return n # An array to store result of subproblems screen = [0] * n # Initializing the optimal lengths array for until 6 input strokes for i in range(1, 7): screen[i - 1] = i # Solve all subproblems in bottom manner for i in range(7, n + 1): # for any keystroke n, we will need to choose between: # 1. pressing Ctrl-V once after copying the A's # obtained by n-3 keystrokes. # 2. pressing Ctrl-V twice after copying the A's # obtained by n-4 keystrokes. # 3. pressing Ctrl-V thrice after copying the A's # obtained by n-5 keystrokes. screen[i - 1] = max(2 * screen[i - 4], max(3 * screen[i - 5], 4 * screen[i - 6])) return screen[n - 1] if __name__ == "__main__": n = 7 print(optimalKeys(n))
C# using System; class GfG { static int optimalKeys(int n) { // The optimal string length is n when n is smaller than 7 if (n <= 6) return n; // An array to store result of subproblems int[] screen = new int[n]; // Initializing the optimal lengths array for until 6 input strokes for (int i = 1; i <= 6; i++) screen[i - 1] = i; // Solve all subproblems in a bottom-up manner for (int i = 7; i <= n; i++) { // for any keystroke n, we will need to choose between: // 1. pressing Ctrl-V once after copying the A's // obtained by n-3 keystrokes. // 2. pressing Ctrl-V twice after copying the A's // obtained by n-4 keystrokes. // 3. pressing Ctrl-V thrice after copying the A's // obtained by n-5 keystrokes. screen[i - 1] = Math.Max(2 * screen[i - 4], Math.Max(3 * screen[i - 5], 4 * screen[i - 6])); } return screen[n - 1]; } static void Main(String[] args) { int n = 7; Console.WriteLine(optimalKeys(n)); } }
JavaScript function optimalKeys(n) { // The optimal string length is n when n is smaller than 7 if (n <= 6) return n; // An array to store result of subproblems let screen = []; // Initializing the optimal lengths array for until 6 input strokes for (let i = 1; i <= 6; i++) screen[i - 1] = i; // Solve all subproblems in bottom-up manner for (let i = 7; i <= n; i++) { // for any keystroke n, we will need to choose between: // 1. pressing Ctrl-V once after copying the A's // obtained by n-3 keystrokes. // 2. pressing Ctrl-V twice after copying the A's // obtained by n-4 keystrokes. // 3. pressing Ctrl-V thrice after copying the A's // obtained by n-5 keystrokes. screen[i - 1] = Math.max(2 * screen[i - 4], Math.max(3 * screen[i - 5], 4 * screen[i - 6])); } return screen[n - 1]; } let n = 7 console.log(optimalKeys(n));
Similar Reads
Number of ways to form a number with maximum Ks in it
Given a number N and a digit K, the task is to calculate the number of ways to form a number with the maximum number of Ks in it, where in an operation, two adjacent digits of N that sum up to K are both replaced with K. Examples : Input :N=1454781, K=9Output : 2Explanation :9 can occur maximum two
7 min read
Minimum number of keypresses to type the given string
Given a string S of length N and a keypad of 9 buttons. We have to configure the mapping of all 26 English characters to the keypad button such that each character is mapped to exactly one button, and each button maps to at most 3 characters. To type a character, we have to press the corresponding b
9 min read
Maximize number from given integers using following operations
Given positive integers N, A, B and C such that 1 ⤠C < N. The task is to maximize the value of B by performing the following operations: A can be incremented by 1 by decreasing 1 from N.Increase the value of B by B + A by subtracting C from N, The above operations can be performed till N ⤠0. Ex
8 min read
Maximum number of removals of given subsequence from a string
Given string str, the task is to count the maximum number of possible operations that can be performed on str. An operation consists of taking a sub-sequence 'gks' from the string and removing it from the string. Examples: Input: str = "ggkssk"Output: 1Explanation: After 1st operation: str = "gsk"No
6 min read
Find maximum number that can be formed using digits of a given number
Given a number, write a program to find a maximum number that can be formed using all of the digits of this number.Examples: Input : 38293367Output : 98763332Input : 1203465Output: 6543210 Simple Approach: The simple method to solve this problem is to extract and store the digits of the given number
6 min read
Count maximum number of words in Array
Given an array of strings arr[], where each arr[i] represents a single sentence with no leading or trailing spaces. Return the count of the maximum number of words that appear in a single string. Input: arr[] = {"Welcome to geeks for geeks", "Happy Coding", "We love gfg"}Output: 5Explanation: The le
5 min read
Print all strings of maximum length from an array of strings
Given an array of strings arr[], the task is to print all the strings of maximum length from the given array. Example: Input: arr[] = {âabaâ, âaaâ, âadâ, âvcdâ, âabaâ}Output: aba vcd abaExplanation:Maximum length among all the strings from the given array is 3.The strings having length equal to 3 fr
7 min read
Smallest number whose set bits are maximum in a given range
Given a positive integer 'l' and 'r'. Find the smallest number 'n' such that l <= n <= r and count of the number of set bits(number of '1's in binary representation) is as maximum as possible. Examples : Input: 1 4Output: 3Explanation:Binary representation from '1' to '4':110 = 0012210 = 01023
9 min read
Find the maximum number of indices that are marked in the given Array
Given a boolean array a[] of size N and integer K. Initially, all are marked false. We have to choose 2 different indexes having the value false such that a[i] * K ⤠a[j] and mark it as true, the task is to find the maximum number of indexes having a value true in array a[]. Examples: Input: a[] = [
5 min read
Find four factors of N with maximum product and sum equal to N
Given an integer [Tex]N [/Tex]. The task is to find all factors of N print the product of four factors of N such that: Sum of the four factors is equal to N.Product of the four factors is maximum. If it is not possible to find 4 such factors then print "Not possible". Note: All the four factors can
10 min read