Minimum number of keypresses to type the given string
Last Updated :
08 Mar, 2024
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 button a certain number of times. For example, to type the first character matched to a button, we press the button once. To type the second character, we press the button twice, and so on. The task is to find the minimum number of keypresses needed to type a given string S using this keypad.
Note: Characters mapped to each button, and the order they are mapped in, cannot be changed.
Input: S = “geeksforgeeks”
Output: 13
Explanation: Optimal keypad configuration,
- 1 -> ‘g’
- 2 -> ‘e’
- 3 -> ‘k’
- 4 -> ‘s’
- 5 -> ‘f’
- 6 -> ‘o’
- 7 -> ‘r’ and for the remaining letters assign any character to any key.
To write “geeksforgeeks”, press 1 once for ‘g’, press 2 once for ‘e’, press 2 again for ‘e’, press 3 again for ‘k’, press 4 again for ‘s’, press 5 for ‘f’, press 6 for ‘o’, press 7 for ‘r’, press 1 once for ‘g’, press 2 once for ‘e’, press 2 again for ‘e’, press 3 again for ‘k’ and press 4 again for ‘s’. Total key presses will be 13.
Input: S = “aabbccddeeffgghhiijklmnopqrstuvwxyz”
Output:
Explanation: Optimal keypad configuration,
- 1 -> ‘ajs’
- 2 -> ‘bkt’
- 3 -> ‘clu’
- 4 -> ‘dmv’
- 5 -> ‘enw’
- 6 -> ‘fox’
- 7 -> ‘gpy’
- 8 -> ‘hqz’
- 9 -> ‘ir’
Total key presses will be 60.
Approach: To solve the problem, follow the below idea:
The problem can be solved using Greedy approach, the idea is to map the most frequent characters in the string as the first character of the button, then lesser frequent characters as the second character of the button and the least frequent character as the third character of the button. This ensures that the buttons are pressed minimum number of times.
Step-by-step algorithm:
- Create an unordered map to store character frequencies and variables for counting keypresses.
- Calculate character frequencies by iterating through the input string.
- Build pairs of character frequencies and characters, storing them in a vector.
- Sort the vector of pairs based on frequencies in ascending order.
- Traverse the sorted pairs in reverse order(most frequent to least frequent).
- For the first 9 characters, add their frequencies to the count.
- For the next 9 characters, add twice their frequencies to the count.
- For the remaining characters, add thrice their frequencies to the count.
- Return the total count as the minimum number of keypresses needed.
Below is the implementation of the algorithm:
C++
#include <bits/stdc++.h>
using namespace std;
int minimumKeypresses(string s)
{
unordered_map< char , int > unmap1;
int count = 0;
vector<pair< int , char > > arr;
for ( auto i : s)
unmap1[i]++;
for ( auto i : unmap1)
arr.push_back({ i.second, i.first });
sort(arr.begin(), arr.end());
for ( int i = arr.size() - 1; i >= 0; i--) {
if (arr.size() - 1 - i + 1 <= 9) {
count += arr[i].first;
}
else if (arr.size() - 1 - i + 1 <= 18) {
count += arr[i].first * 2;
}
else {
count += arr[i].first * 3;
}
}
return count;
}
int main()
{
string s = "geeksforgeeks" ;
cout << "The minimum number of keypresses needed to "
"type the string '"
<< s << "' is: " << minimumKeypresses(s) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int minimumKeypresses(String s) {
Map<Character, Integer> unmap1 = new HashMap<>();
int count = 0 ;
List<Pair<Integer, Character>> arr = new ArrayList<>();
for ( char i : s.toCharArray()) {
unmap1.put(i, unmap1.getOrDefault(i, 0 ) + 1 );
}
for (Map.Entry<Character, Integer> entry : unmap1.entrySet()) {
arr.add( new Pair<>(entry.getValue(), entry.getKey()));
}
arr.sort(Comparator.comparingInt(Pair::getFirst));
for ( int i = arr.size() - 1 ; i >= 0 ; i--) {
if (arr.size() - 1 - i + 1 <= 9 ) {
count += arr.get(i).getFirst();
}
else if (arr.size() - 1 - i + 1 <= 18 ) {
count += arr.get(i).getFirst() * 2 ;
}
else {
count += arr.get(i).getFirst() * 3 ;
}
}
return count;
}
public static void main(String[] args) {
String s = "geeksforgeeks" ;
System.out.println( "The minimum number of keypresses needed to "
+ "type the string '" + s + "' is: " + minimumKeypresses(s));
}
static class Pair<K, V> {
private K first;
private V second;
public Pair(K first, V second) {
this .first = first;
this .second = second;
}
public K getFirst() {
return first;
}
public V getSecond() {
return second;
}
}
}
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static int MinimumKeypresses( string s)
{
var frequencyMap = new Dictionary< char , int >();
foreach ( var ch in s)
{
if (!frequencyMap.ContainsKey(ch))
{
frequencyMap[ch] = 0;
}
frequencyMap[ch]++;
}
var list = frequencyMap.Select(kvp => new KeyValuePair< int , char >(kvp.Value, kvp.Key)).ToList();
list.Sort((pair1, pair2) => pair1.Key.CompareTo(pair2.Key));
int count = 0;
for ( int i = list.Count - 1; i >= 0; i--)
{
int position = list.Count - 1 - i;
if (position < 9)
{
count += list[i].Key;
}
else if (position < 18)
{
count += list[i].Key * 2;
}
else
{
count += list[i].Key * 3;
}
}
return count;
}
static void Main( string [] args)
{
string s = "geeksforgeeks" ;
Console.WriteLine($ "The minimum number of keypresses needed to type the string '{s}' is: {MinimumKeypresses(s)}" );
}
}
|
Javascript
function minimumKeypresses(s) {
let unmap1 = new Map();
let count = 0;
let arr = [];
for (let i of s) {
unmap1.set(i, (unmap1.get(i) || 0) + 1);
}
for (let [key, value] of unmap1) {
arr.push([value, key]);
}
arr.sort((a, b) => a[0] - b[0]);
for (let i = arr.length - 1; i >= 0; i--) {
if (arr.length - 1 - i + 1 <= 9) {
count += arr[i][0];
}
else if (arr.length - 1 - i + 1 <= 18) {
count += arr[i][0] * 2;
}
else {
count += arr[i][0] * 3;
}
}
return count;
}
let s = "geeksforgeeks" ;
console.log(`The minimum number of keypresses needed to type the string '${s}' is: ${minimumKeypresses(s)}`);
|
Python3
def minimum_keypresses(s):
unmap1 = {}
count = 0
arr = []
for i in s:
if i in unmap1:
unmap1[i] + = 1
else :
unmap1[i] = 1
for i in unmap1.items():
arr.append(i)
arr.sort()
for i in range ( len (arr) - 1 , - 1 , - 1 ):
if len (arr) - 1 - i + 1 < = 9 :
count + = arr[i][ 1 ]
elif len (arr) - 1 - i + 1 < = 18 :
count + = arr[i][ 1 ] * 2
else :
count + = arr[i][ 1 ] * 3
return count
s = "geeksforgeeks"
print (f "The minimum number of keypresses needed to type the string '{s}' is: {minimum_keypresses(s)}" )
|
Output
The minimum number of keypresses needed to type the string 'geeksforgeeks' is: 13
Time Complexity: O(Nlog(N)), where N is the length of input string S.
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...