Given string str of size N consisting of the first N alphabets and a matrix mat[] of size N*N where mat[i][j] represents the cost of placing ith character of the alphabet before the jth character in the string. The task is to find the minimum cost to generate any permutation of the given string.
Examples:
Input:str = “abcde”, mat[][]= {{0, 5, 1, 5, 3}, {4, 0, 9, 4, 2}, {7, 9, 0, 10, 7}, {1, 2, 8, 0, 2}, {3, 9, 7, 7, 0}}
Output: 8
Explanation:
Permutation ‘dbeac’ can be generated at a minimum cost of 8.
Cost of placing d = 0 (since there is no prev character)
Cost of placing b after d = mat[4][2] = 2
Cost of placing e after b = mat[2][5] = 2
Cost of placing a after e = mat[5][1] = 3
Cost of placing c after a = mat[1][3] = 1
Total cost = 2 + 2 + 3 + 1 = 8Input: str = “abcde”, mat[][] = {{0, 9, 4, 8, 10}, {7, 0, 9, 5, 5}, {2, 8, 0, 4, 1}, {4, 10, 5, 0, 5}, {4, 3, 4, 7, 0 }}
Output: 13
Naive Approach: The naive idea is to generate all possible permutations of the given string and find the cost of every permutation. Then print the minimum cost among all possible costs.
Time Complexity: O(N*N!)
Auxiliary Space: O(N!)
Efficient Approach: To optimize the above approach the idea is to use Dynamic Programming with Bit Masking. Observe that all the characters are distinct and there are only 26 alphabets possible. So use a mask to store the presence of each character. Below are the steps:
- Iterate through all characters of the string and place each character at each position if it is available i.e., the bit is set in the mask.
- Then, place the character in the current position and calculate the cost of placing the character.
- Move to the next position by flipping the bit of the current character.
- At each iteration, the mask represents the number of available characters for the current position.
- After completing the above steps, print the minimum cost among all the costs calculated.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function that returns true // if the current bit is set bool check( int mask, int i) { int c = (mask & (1 << i)); return c != 0; } // Function to find the minimum cost // to form any permutation of string s int solve(vector<vector< int >> a, string s, int n, int prev, int mask, vector<vector< int >> dp) { // Base Case if (mask == 0) return 0; // Return the precomputed state if (dp[mask][prev + 1] != -1) return dp[mask][prev + 1]; int ans = 10000; // Iterate over the string and // check all possible characters // available for current position for ( int i = 0; i < s.length(); i++) { int id = s[i] - 'a' ; // Check if character can be // placed at current position if (check(mask, id)) { // As there is no previous // character so the cost // for 1st character is 0 if (prev == -1) { ans = min(ans, solve(a, s, n, id, mask ^ (1 << id), dp)); } // Find the cost of current // character and move to next // position else { ans = min(ans, a[prev][id] + solve(a, s, n, id, mask ^ (1 << id), dp)); } } } // Store the answer for each // current state dp[mask][prev + 1] = ans; return ans; } // Function that generates any // permutation of the given // string with minimum cost void generatePermutation( int mask, int n, vector<vector< int >> a, string s) { // Initialize dp table vector<vector< int >> dp((1 << n) + 5 , vector< int > (n + 5, -1)); // Set all the bits of the // current character id for ( int i = 0; i < s.length(); i++) { int id = s[i] - 'a' ; mask |= (1 << id); } // Minimum cost of generating // the permutation cout << solve(a, s, n, -1, mask, dp) << endl; } // Driver Code int main() { int N = 5; string str = "abcde" ; vector<vector< int >> mat = { { 0, 5, 1, 5, 3 }, { 4, 0, 9, 4, 2 }, { 7, 9, 0, 10, 7 }, { 1, 2, 8, 0, 2 }, { 3, 9, 7, 7, 0 } }; // Function Call generatePermutation(0, N, mat, str); return 0; } // This code is contributed by divyeshrabadiya07 |
Java
// Java program for the above approach import java.util.*; public class Main { // Function to find the minimum cost // to form any permutation of string s public static int solve( int a[][], String s, int n, int prev, int mask, int [][] dp) { // Base Case if (mask == 0 ) return 0 ; // Return the precomputed state if (dp[mask][prev + 1 ] != - 1 ) return dp[mask][prev + 1 ]; int ans = 10000 ; // Iterate over the string and // check all possible characters // available for current position for ( int i = 0 ; i < s.length(); i++) { int id = s.charAt(i) - 'a' ; // Check if character can be // placed at current position if (check(mask, id)) { // As there is no previous // character so the cost // for 1st character is 0 if (prev == - 1 ) { ans = Math.min(ans, solve( a, s, n, id, mask ^ ( 1 << id), dp)); } // Find the cost of current // character and move to next // position else { ans = Math.min( ans, a[prev][id] + solve( a, s, n, id, mask ^ ( 1 << id), dp)); } } } // Store the answer for each // current state dp[mask][prev + 1 ] = ans; return ans; } // Function that returns true // if the current bit is set public static boolean check( int mask, int i) { int c = (mask & ( 1 << i)); return c != 0 ; } // Function that generates any // permutation of the given // string with minimum cost static void generatePermutation( int mask, int n, int a[][], String s) { // Initialize dp table int dp[][] = new int [( 1 << n) + 5 ][n + 5 ]; for ( int i[] : dp) Arrays.fill(i, - 1 ); // Set all the bits of the // current character id for ( int i = 0 ; i < s.length(); i++) { int id = s.charAt(i) - 'a' ; mask |= ( 1 << id); } // Minimum cost of generating // the permutation System.out.println(solve( a, s, n, - 1 , mask, dp)); } // Driver Code public static void main(String args[]) { int N = 5 ; String str = "abcde" ; int mat[][] = { { 0 , 5 , 1 , 5 , 3 }, { 4 , 0 , 9 , 4 , 2 }, { 7 , 9 , 0 , 10 , 7 }, { 1 , 2 , 8 , 0 , 2 }, { 3 , 9 , 7 , 7 , 0 } }; // Function Call generatePermutation( 0 , N, mat, str); } } |
Python3
# Python3 program for the # above approach # Function to find the # minimum cost to form # any permutation of # string s def solve(a, s, n, prev, mask, dp): # Base Case if (mask = = 0 ): return 0 ; # Return the precomputed state if (dp[mask][prev + 1 ] ! = - 1 ): return dp[mask][prev + 1 ]; ans = 10000 ; # Iterate over the string and # check all possible characters # available for current position for i in range ( len (s)): id = ord (s[i]) - ord ( 'a' ); # Check if character can be # placed at current position if (check(mask, id )): # As there is no previous # character so the cost # for 1st character is 0 if (prev = = - 1 ): ans = min (ans, solve(a, s, n, id , mask ^ ( 1 << id ), dp)); # Find the cost of current # character and move to next # position else : ans = min (ans, a[prev][ id ] + solve(a, s, n, id , mask ^ ( 1 << id ), dp)); # Store the answer for each # current state dp[mask][prev + 1 ] = ans; return ans; # Function that returns # True if the current # bit is set def check(mask, i): c = (mask & ( 1 << i)); return c ! = 0 ; # Function that generates any # permutation of the given # string with minimum cost def generatePermutation(mask, n, a, s): # Initialize dp table dp = [[ - 1 for i in range (n + 5 )] for j in range (( 1 << n) + 5 )] # Set all the bits of the # current character id for i in range ( len (s)): id = ord (s[i]) - ord ( 'a' ); mask | = ( 1 << id ); # Minimum cost of generating # the permutation print (solve(a, s, n, - 1 , mask, dp)); # Driver Code if __name__ = = '__main__' : N = 5 ; str = "abcde" ; mat = [[ 0 , 5 , 1 , 5 , 3 ], [ 4 , 0 , 9 , 4 , 2 ], [ 7 , 9 , 0 , 10 , 7 ], [ 1 , 2 , 8 , 0 , 2 ], [ 3 , 9 , 7 , 7 , 0 ]]; # Function Call generatePermutation( 0 , N, mat, str ); # This code is contributed by gauravrajput1 |
C#
// C# program for the // above approach using System; class GFG{ // Function to find the minimum cost // to form any permutation of string s public static int solve( int [,]a, String s, int n, int prev, int mask, int [,] dp) { // Base Case if (mask == 0) return 0; // Return the precomputed state if (dp[mask,prev + 1] != -1) return dp[mask, prev + 1]; int ans = 10000; // Iterate over the string and // check all possible characters // available for current position for ( int i = 0; i < s.Length; i++) { int id = s[i] - 'a' ; // Check if character can be // placed at current position if (check(mask, id)) { // As there is no previous // character so the cost // for 1st character is 0 if (prev == -1) { ans = Math.Min(ans, solve(a, s, n, id, mask ^ (1 << id), dp)); } // Find the cost of current // character and move to next // position else { ans = Math.Min(ans, a[prev,id] + solve(a, s, n, id, mask ^ (1 << id), dp)); } } } // Store the answer for each // current state dp[mask, prev + 1] = ans; return ans; } // Function that returns true // if the current bit is set public static bool check( int mask, int i) { int c = (mask & (1 << i)); return c != 0; } // Function that generates any // permutation of the given // string with minimum cost static void generatePermutation( int mask, int n, int [,]a, String s) { // Initialize dp table int [,]dp = new int [(1 << n) + 5, n + 5]; for ( int i = 0; i < (1 << n) + 5; i++) for ( int j = 0; j < n + 5; j++) dp[i, j] = -1; // Set all the bits of the // current character id for ( int i = 0; i < s.Length; i++) { int id = s[i] - 'a' ; mask |= (1 << id); } // Minimum cost of generating // the permutation Console.WriteLine(solve(a, s, n, -1, mask, dp)); } // Driver Code public static void Main(String []args) { int N = 5; String str = "abcde" ; int [,]mat = {{0, 5, 1, 5, 3}, {4, 0, 9, 4, 2}, {7, 9, 0, 10, 7}, {1, 2, 8, 0, 2}, {3, 9, 7, 7, 0}}; // Function Call generatePermutation(0, N, mat, str); } } // This code is contributed by Rajput-Ji |
Javascript
<script> // Javascript program for the above approach // Function that returns true // if the current bit is set function check(mask, i) { var c = (mask & (1 << i)); return c != 0; } // Function to find the minimum cost // to form any permutation of string s function solve(a, s, n, prev, mask, dp) { // Base Case if (mask == 0) return 0; // Return the precomputed state if (dp[mask][prev + 1] != -1) return dp[mask][prev + 1]; var ans = 10000; // Iterate over the string and // check all possible characters // available for current position for ( var i = 0; i < s.length; i++) { var id = s[i].charCodeAt(0) - 'a' .charCodeAt(0); // Check if character can be // placed at current position if (check(mask, id)) { // As there is no previous // character so the cost // for 1st character is 0 if (prev == -1) { ans = Math.min(ans, solve(a, s, n, id, mask ^ (1 << id), dp)); } // Find the cost of current // character and move to next // position else { ans = Math.min(ans, a[prev][id] + solve(a, s, n, id, mask ^ (1 << id), dp)); } } } // Store the answer for each // current state dp[mask][prev + 1] = ans; return ans; } // Function that generates any // permutation of the given // string with minimum cost function generatePermutation(mask, n, a, s) { // Initialize dp table var dp = Array.from(Array((1 << n) + 5), ()=> Array(n + 5).fill(-1)); // Set all the bits of the // current character id for ( var i = 0; i < s.length; i++) { var id = s[i].charCodeAt(0) - 'a' .charCodeAt(0); mask |= (1 << id); } // Minimum cost of generating // the permutation document.write( solve(a, s, n, -1, mask, dp) + "<br>" ); } // Driver Code var N = 5; var str = "abcde" ; var mat = [ [ 0, 5, 1, 5, 3 ], [ 4, 0, 9, 4, 2 ], [ 7, 9, 0, 10, 7 ], [ 1, 2, 8, 0, 2 ], [ 3, 9, 7, 7, 0 ] ]; // Function Call generatePermutation(0, N, mat, str); // This code is contributed by noob2000. </script> |
8
Time Complexity: O(N*2N)
Auxiliary Space: O(N*2N)
Using Brute Force with Recursion in python:
Approach:
The idea is to generate all possible permutations of the given string and calculate the cost for each permutation. Finally, return the minimum cost among all the permutations.
The get_min_cost function takes two inputs, a string str and a 2D matrix mat that represents the cost of swapping each pair of characters. The function returns the minimum cost of swapping any pair of characters in the input string such that the resulting string is lexicographically sorted.
The function first generates all permutations of the input string using a recursive function permute, which takes the current permutation string s, left and right indices of the current permutation l and r respectively. The function generates permutations by swapping each character with every other character in the string, recursively calling itself for each swap until the left and right indices are the same, indicating that the string is fully permuted.
For each permutation, the function calculates the cost of swapping pairs of characters using the input matrix mat and returns the minimum cost of all permutations. The cost is calculated by iterating through each character in the permutation, and adding the cost of swapping it with the previous character. The cost of swapping two characters is obtained by indexing the matrix using the ASCII value of the characters.
C++
#include <bits/stdc++.h> using namespace std; // Function to permute the string and calculate all permutations void permute(string s, int l, int r, vector<string>& perms) { if (l == r) { perms.push_back(s); } else { for ( int i = l; i <= r; i++) { swap(s[l], s[i]); permute(s, l + 1, r, perms); swap(s[l], s[i]); // Backtrack to the original state } } } // Function to get the minimum cost int get_min_cost(string str, vector<vector< int >>& mat) { int n = str.length(); // vector of string to store the permutations vector<string> perms; permute(str, 0, n - 1, perms); // Calculate cost for each permutation and return the minimum cost int min_cost = INT_MAX; for ( const string& perm : perms) { int cost = 0; for ( int i = 1; i < n; i++) { int row = perm[i - 1] - 'a' ; int col = perm[i] - 'a' ; cost += mat[row][col]; } if (cost < min_cost) { min_cost = cost; } } return min_cost; } //Driver code int main() { //Test case input string str1 = "abcde" ; vector<vector< int >> mat1 = {{0, 5, 1, 5, 3}, {4, 0, 9, 4, 2}, {7, 9, 0, 10, 7}, {1, 2, 8, 0, 2}, {3, 9, 7, 7, 0}}; //Function call int result = get_min_cost(str1, mat1); cout << "Output: " << result << endl; // Output: 8 return 0; } |
Java
import java.util.ArrayList; import java.util.List; public class StringPermutationMinCost { // Function to permute the string and calculate all permutations static void permute(String s, int l, int r, List<String> perms) { if (l == r) { perms.add(s); } else { for ( int i = l; i <= r; i++) { s = swap(s, l, i); permute(s, l + 1 , r, perms); s = swap(s, l, i); // Backtrack to the original state } } } // Helper function to swap characters in a string static String swap(String str, int i, int j) { char [] charArray = str.toCharArray(); char temp = charArray[i]; charArray[i] = charArray[j]; charArray[j] = temp; return new String(charArray); } // Function to get the minimum cost static int getMinCost(String str, int [][] mat) { int n = str.length(); List<String> perms = new ArrayList<>(); permute(str, 0 , n - 1 , perms); // Calculate cost for each permutation and return the minimum cost int minCost = Integer.MAX_VALUE; for (String perm : perms) { int cost = 0 ; for ( int i = 1 ; i < n; i++) { int row = perm.charAt(i - 1 ) - 'a' ; int col = perm.charAt(i) - 'a' ; cost += mat[row][col]; } if (cost < minCost) { minCost = cost; } } return minCost; } public static void main(String[] args) { // Test case input String str1 = "abcde" ; int [][] mat1 = {{ 0 , 5 , 1 , 5 , 3 }, { 4 , 0 , 9 , 4 , 2 }, { 7 , 9 , 0 , 10 , 7 }, { 1 , 2 , 8 , 0 , 2 }, { 3 , 9 , 7 , 7 , 0 }}; // Function call int result = getMinCost(str1, mat1); System.out.println(result); // Output: 8 } } |
Python3
def get_min_cost( str , mat): n = len ( str ) perms = [] # Generate all permutations of the string def permute(s, l, r): if l = = r: perms.append(s.copy()) else : for i in range (l, r + 1 ): s[l], s[i] = s[i], s[l] permute(s, l + 1 , r) s[l], s[i] = s[i], s[l] permute( list ( str ), 0 , n - 1 ) # Calculate cost for each permutation and return the minimum cost min_cost = float ( 'inf' ) for perm in perms: cost = 0 for i in range ( 1 , n): cost + = mat[ ord (perm[i - 1 ]) - 97 ][ ord (perm[i]) - 97 ] if cost < min_cost: min_cost = cost return min_cost # Example usage str1 = "abcde" mat1 = [[ 0 , 5 , 1 , 5 , 3 ], [ 4 , 0 , 9 , 4 , 2 ], [ 7 , 9 , 0 , 10 , 7 ], [ 1 , 2 , 8 , 0 , 2 ], [ 3 , 9 , 7 , 7 , 0 ]] print (get_min_cost(str1, mat1)) # Output: 8 |
C#
using System; using System.Collections.Generic; class GFG { // Function to permute the string and calculate all // permutations static void Permute( string s, int l, int r, List< string > perms) { if (l == r) { perms.Add(s); } else { for ( int i = l; i <= r; i++) { s = SwapChars(s, l, i); Permute(s, l + 1, r, perms); s = SwapChars( s, l, i); // Backtrack to the original state } } } // Helper function to swap characters in a string static string SwapChars( string s, int i, int j) { char [] charArray = s.ToCharArray(); char temp = charArray[i]; charArray[i] = charArray[j]; charArray[j] = temp; return new string (charArray); } // Function to get the minimum cost static int GetMinCost( string str, int [][] mat) { int n = str.Length; // list of strings to store the permutations List< string > perms = new List< string >(); Permute(str, 0, n - 1, perms); // Calculate cost for each permutation and return // the minimum cost int minCost = int .MaxValue; foreach ( string perm in perms) { int cost = 0; for ( int i = 1; i < n; i++) { int row = perm[i - 1] - 'a' ; int col = perm[i] - 'a' ; cost += mat[row][col]; } if (cost < minCost) { minCost = cost; } } return minCost; } // Driver code static void Main() { // Test case input string str1 = "abcde" ; int [][] mat1 = new int [][] { new int [] { 0, 5, 1, 5, 3 }, new int [] { 4, 0, 9, 4, 2 }, new int [] { 7, 9, 0, 10, 7 }, new int [] { 1, 2, 8, 0, 2 }, new int [] { 3, 9, 7, 7, 0 } }; // Function call int result = GetMinCost(str1, mat1); Console.WriteLine(result); } } |
Javascript
class GFG { // Function to permute the string and calculate all permutations static Permute(s, l, r, perms) { if (l === r) { perms.push(s); } else { for (let i = l; i <= r; i++) { s = this .SwapChars(s, l, i); this .Permute(s, l + 1, r, perms); s = this .SwapChars(s, l, i); // Backtrack to the original state } } } // Helper function to swap characters in a string static SwapChars(s, i, j) { const charArray = s.split( '' ); const temp = charArray[i]; charArray[i] = charArray[j]; charArray[j] = temp; return charArray.join( '' ); } // Function to get the minimum cost static GetMinCost(str, mat) { const n = str.length; // List of strings to store the permutations const perms = []; this .Permute(str, 0, n - 1, perms); // Calculate cost for each permutation and return the minimum cost let minCost = Number.MAX_SAFE_INTEGER; perms.forEach(perm => { let cost = 0; for (let i = 1; i < n; i++) { const row = perm.charCodeAt(i - 1) - 'a' .charCodeAt(0); const col = perm.charCodeAt(i) - 'a' .charCodeAt(0); cost += mat[row][col]; } if (cost < minCost) { minCost = cost; } }); return minCost; } // Driver code static Main() { // Test case input const str1 = 'abcde' ; const mat1 = [ [0, 5, 1, 5, 3], [4, 0, 9, 4, 2], [7, 9, 0, 10, 7], [1, 2, 8, 0, 2], [3, 9, 7, 7, 0], ]; // Function call const result = this .GetMinCost(str1, mat1); console.log(result); } } // Call the Main method to run the code GFG.Main(); |
8
Time Complexity: O(n!), where n is the length of the string. (as we generate all permutations)
Space Complexity: O(n), where n is the length of the string. (as we store the current permutation in memory)
Approch 3 : Dynamic Programming
The provided code solves the given problem using dynamic programming. Memorization is employed to prevent recomputations and store the status of the subproblems. The current state is sent to the main function “solve” as (mask, prev), where “mask” denotes the set of characters that are now accessible and “prev” denotes the character that was previously positioned. The string is then iterated over, and each conceivable character that could fit in the present location is checked. It repeatedly calls’solve’ with the updated state and computes the cost of inserting the current character based on the previous character and the cost matrix ‘a’ for each character that may be placed at the current position. The current state’s dp table then contains the character placement with the lowest cost out of all potential character placements.
Algorithm Steps of the given code are as follows:
1. Define a function check() to check if the current bit is set in the mask.
2. Define a recursive function solve() to find the minimum cost to generate any permutation of the given string.
3. In solve(), check for the base case where mask becomes 0, i.e., all the characters have been used.
4. In solve(), check if the current state has already been computed in the dp table, if yes, then return the precomputed value.
5. In solve(), iterate over the string and check all possible characters available for the current position.
6. In solve(), if the character can be placed at the current position, then check if there is no previous character, in which case the cost for the first character is 0.
7. In solve(), else find the cost of the current character and move to the next position.
8. In solve(), store the answer for each current state in the dp table.
9. Define a function generatePermutation() to generate any permutation of the given string with minimum cost.
10. In generatePermutation(), initialize the dp table and set all the bits of the current character id.
11. In generatePermutation(), call the solve() function with initial parameters and output the minimum cost.
12. In main(), define the input string and cost matrix and call the generatePermutation() function with the inputs.
13. End of the program.
C++
#include <iostream> #include <vector> #include <cstring> using namespace std; int check( int mask, int i) { int c = (mask & (1 << i)); return c != 0; } int solve(vector<vector< int >>& a, string s, int n, int prev, int mask, vector<vector< int >>& dp) { // Base Case if (mask == 0) { return 0; } // Return the precomputed state if (dp[mask][prev + 1] != -1) { return dp[mask][prev + 1]; } int ans = 10000; // Iterate over the string and check all possible characters available for the current position for ( int i = 0; i < s.length(); i++) { int id = s[i] - 'a' ; // Check if the character can be placed at the current position if (check(mask, id)) { // As there is no previous character so the cost for the 1st character is 0 if (prev == -1) { ans = min(ans, solve(a, s, n, id, mask ^ (1 << id), dp)); } // Find the cost of the current character and move to the next position else { ans = min(ans, a[prev][id] + solve(a, s, n, id, mask ^ (1 << id), dp)); } } } // Store the answer for each current state dp[mask][prev + 1] = ans; return ans; } // Function that generates any permutation of the given string with the minimum cost void generate_permutation( int mask, int n, vector<vector< int >>& a, string s) { // Initialize dp table vector<vector< int >> dp((1 << n) + 5, vector< int >(n + 5, -1)); // Set all the bits of the current character id for ( int i = 0; i < s.length(); i++) { int id = s[i] - 'a' ; mask |= (1 << id); } // Minimum cost of generating the permutation cout << solve(a, s, n, -1, mask, dp) << endl; } int main() { int N = 5; string str = "abcde" ; vector<vector< int >> mat = { {0, 5, 1, 5, 3}, {4, 0, 9, 4, 2}, {7, 9, 0, 10, 7}, {1, 2, 8, 0, 2}, {3, 9, 7, 7, 0} }; // Function Call generate_permutation(0, N, mat, str); return 0; } |
Java
import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.Collections; public class MinimumCostPermutation { public static void main(String[] args) { int N = 5 ; String str = "abcde" ; List<List<Integer>> mat = Arrays.asList( Arrays.asList( 0 , 5 , 1 , 5 , 3 ), Arrays.asList( 4 , 0 , 9 , 4 , 2 ), Arrays.asList( 7 , 9 , 0 , 10 , 7 ), Arrays.asList( 1 , 2 , 8 , 0 , 2 ), Arrays.asList( 3 , 9 , 7 , 7 , 0 ) ); // Function Call generatePermutation( 0 , N, mat, str); } public static int check( int mask, int i) { int c = (mask & ( 1 << i)); return c != 0 ? 1 : 0 ; } public static int solve(List<List<Integer>> a, String s, int n, int prev, int mask, List<List<Integer>> dp) { // Base Case if (mask == 0 ) { return 0 ; } // Return the precomputed state if (dp.get(mask).get(prev + 1 ) != - 1 ) { return dp.get(mask).get(prev + 1 ); } int ans = 10000 ; // Iterate over the string and check all possible characters available for the current position for ( int i = 0 ; i < s.length(); i++) { int id = s.charAt(i) - 'a' ; // Check if the character can be placed at the current position if (check(mask, id) == 1 ) { // As there is no previous character so the cost for the 1st character is 0 if (prev == - 1 ) { ans = Math.min(ans, solve(a, s, n, id, mask ^ ( 1 << id), dp)); } // Find the cost of the current character and move to the next position else { ans = Math.min(ans, a.get(prev).get(id) + solve(a, s, n, id, mask ^ ( 1 << id), dp)); } } } // Store the answer for each current state dp.get(mask).set(prev + 1 , ans); return ans; } // Function that generates any permutation of the given string with the minimum cost public static void generatePermutation( int mask, int n, List<List<Integer>> a, String s) { // Initialize dp table List<List<Integer>> dp = new ArrayList<>(); for ( int i = 0 ; i < ( 1 << n) + 5 ; i++) { List<Integer> row = new ArrayList<>(Arrays.asList( new Integer[n + 5 ])); Collections.fill(row, - 1 ); dp.add(row); } // Set all the bits of the current character id for ( int i = 0 ; i < s.length(); i++) { int id = s.charAt(i) - 'a' ; mask |= ( 1 << id); } // Minimum cost of generating the permutation System.out.println(solve(a, s, n, - 1 , mask, dp)); } } |
Python3
# python3 implementaton def check(mask, i): c = (mask & ( 1 << i)) return c ! = 0 def solve(a, s, n, prev, mask, dp): # Base Case if mask = = 0 : return 0 # Return the precomputed state if dp[mask][prev + 1 ] ! = - 1 : return dp[mask][prev + 1 ] ans = 10000 # Iterate over the string and check all possible characters available for current position for i in range ( len (s)): id = ord (s[i]) - ord ( 'a' ) # Check if character can be placed at current position if check(mask, id ): # As there is no previous character so the cost for 1st character is 0 if prev = = - 1 : ans = min (ans, solve(a, s, n, id , mask ^ ( 1 << id ), dp)) # Find the cost of current character and move to next position else : ans = min (ans, a[prev][ id ] + solve(a, s, n, id , mask ^ ( 1 << id ), dp)) # Store the answer for each current state dp[mask][prev + 1 ] = ans return ans # Function that generates any permutation of the given string with minimum cost def generate_permutation(mask, n, a, s): # Initialize dp table dp = [[ - 1 for i in range (n + 5 )] for j in range (( 1 << n) + 5 )] # Set all the bits of the current character id for i in range ( len (s)): id = ord (s[i]) - ord ( 'a' ) mask | = ( 1 << id ) # Minimum cost of generating the permutation print (solve(a, s, n, - 1 , mask, dp)) # Driver Code if __name__ = = '__main__' : N = 5 str = "abcde" mat = [[ 0 , 5 , 1 , 5 , 3 ], [ 4 , 0 , 9 , 4 , 2 ], [ 7 , 9 , 0 , 10 , 7 ], [ 1 , 2 , 8 , 0 , 2 ], [ 3 , 9 , 7 , 7 , 0 ]] # Function Call generate_permutation( 0 , N, mat, str ) |
8
Time Complexity : O(N * 2^N), where N is the size of the string.
Space Auxilitary Complexity : O(2^N * N).
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!