 GeeksforGeeks App
Open App Browser
Continue

# Minimum cost to sort strings using reversal operations of different costs

Given an array of strings and costs of reversing all strings, we need to sort the array. We cannot move strings in array, only string reversal is allowed. We need to reverse some of the strings in such a way that all strings make a lexicographic order and cost is also minimized. If it is not possible to sort strings in any way, output not possible.

Examples:

```Input  : arr[] = {“aa”, “ba”, “ac”},
reverseCost[] = {1, 3, 1}
Output : Minimum cost of sorting = 1
Explanation : We can make above string array sorted
by reversing one of 2nd or 3rd string, but reversing
2nd string cost 3, so we will reverse 3rd string to
make string array sorted with a cost 1 which is
minimum.```

We can solve this problem using dynamic programming. We make a 2D array for storing the minimum cost of sorting.

```dp[i][j] represents the minimum cost to make first i
strings sorted.
j = 1 means i'th string is reversed.
j = 0 means i'th string is not reversed.

Value of dp[i][j] is computed using dp[i-1] and
dp[i-1].

Computation of dp[i]
If arr[i] is greater than str[i-1], we update dp[i]
by dp[i-1]
If arr[i] is greater than reversal of previous string
we update dp[i] by dp[i-1]

Same procedure is applied to compute dp[i], we
reverse str[i] before applying the procedure.

At the end we will choose minimum of dp[N-1] and
dp[N-1] as our final answer if both of them not
updated yet even once, we will flag that sorting is
not possible.```

Below is the implementation of above idea.

## C++

 `// C++ program to get minimum cost to sort``// strings by reversal operation``#include ``using` `namespace` `std;` `// Returns minimum cost for sorting arr[]``// using reverse operation. This function``// returns -1 if it is not possible to sort.``int` `minCost(string arr[], ``int` `cost[], ``int` `N)``{``    ``// dp[i][j] represents the minimum cost to``    ``// make first i strings sorted.``    ``// j = 1 means i'th string is reversed.``    ``// j = 0 means i'th string is not reversed.``    ``int` `dp[N];` `    ``// initializing dp array for first string``    ``dp = 0;``    ``dp = cost;` `    ``// getting array of reversed strings``    ``string revStr[N];``    ``for` `(``int` `i = 0; i < N; i++)``    ``{``        ``revStr[i] = arr[i];``        ``reverse(revStr[i].begin(), revStr[i].end());``    ``}` `    ``string curStr;``    ``int` `curCost;` `    ``// looping for all strings``    ``for` `(``int` `i = 1; i < N; i++)``    ``{``        ``// Looping twice, once for string and once``        ``// for reversed string``        ``for` `(``int` `j = 0; j < 2; j++)``        ``{``            ``dp[i][j] = INT_MAX;` `            ``// getting current string and current``            ``// cost according to j``            ``curStr = (j == 0) ? arr[i] : revStr[i];``            ``curCost = (j == 0) ? 0 : cost[i];` `            ``// Update dp value only if current string``            ``// is lexicographically larger``            ``if` `(curStr >= arr[i - 1])``                ``dp[i][j] = min(dp[i][j], dp[i-1] + curCost);``            ``if` `(curStr >= revStr[i - 1])``                ``dp[i][j] = min(dp[i][j], dp[i-1] + curCost);``        ``}``    ``}` `    ``// getting minimum from both entries of last index``    ``int` `res = min(dp[N-1], dp[N-1]);` `    ``return` `(res == INT_MAX)? -1 : res;``}` `// Driver code to test above methods``int` `main()``{``    ``string arr[] = {``"aa"``, ``"ba"``, ``"ac"``};``    ``int` `cost[] = {1, 3, 1};``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``int` `res = minCost(arr, cost, N);``    ``if` `(res == -1)``        ``cout << ``"Sorting not possible\n"``;``    ``else``        ``cout << ``"Minimum cost to sort strings is "``            ``<< res;``}`

## Java

 `// Java program to get minimum cost to sort``// strings by reversal operation``import` `java.util.*;` `class` `GFG``{` `// Returns minimum cost for sorting arr[]``// using reverse operation. This function``// returns -1 if it is not possible to sort.``static` `int` `minCost(String arr[], ``int` `cost[], ``int` `N)``{``    ``// dp[i][j] represents the minimum cost to``    ``// make first i strings sorted.``    ``// j = 1 means i'th string is reversed.``    ``// j = 0 means i'th string is not reversed.``    ``int` `[][]dp = ``new` `int``[N][``2``];` `    ``// initializing dp array for first string``    ``dp[``0``][``0``] = ``0``;``    ``dp[``0``][``1``] = cost[``0``];` `    ``// getting array of reversed strings``    ``String []revStr = ``new` `String[N];``    ``for` `(``int` `i = ``0``; i < N; i++)``    ``{``        ``revStr[i] = arr[i];``        ``revStr[i] = reverse(revStr[i], ``0``,``                            ``revStr[i].length() - ``1``);``    ``}` `    ``String curStr = ``""``;``    ``int` `curCost;` `    ``// looping for all strings``    ``for` `(``int` `i = ``1``; i < N; i++)``    ``{``        ``// Looping twice, once for string and once``        ``// for reversed string``        ``for` `(``int` `j = ``0``; j < ``2``; j++)``        ``{``            ``dp[i][j] = Integer.MAX_VALUE;` `            ``// getting current string and current``            ``// cost according to j``            ``curStr = (j == ``0``) ? arr[i] : revStr[i];``            ``curCost = (j == ``0``) ? ``0` `: cost[i];` `            ``// Update dp value only if current string``            ``// is lexicographically larger``            ``if` `(curStr.compareTo(arr[i - ``1``]) >= ``0``)``                ``dp[i][j] = Math.min(dp[i][j],``                                    ``dp[i - ``1``][``0``] + curCost);``            ``if` `(curStr.compareTo(revStr[i - ``1``]) >= ``0``)``                ``dp[i][j] = Math.min(dp[i][j],``                                    ``dp[i - ``1``][``1``] + curCost);``        ``}``    ``}` `    ``// getting minimum from both entries of last index``    ``int` `res = Math.min(dp[N - ``1``][``0``], dp[N - ``1``][``1``]);` `    ``return` `(res == Integer.MAX_VALUE)? -``1` `: res;``}` `static` `String reverse(String s, ``int` `start, ``int` `end)``{` `    ``// Temporary variable to store character``    ``char` `temp;``    ``char` `[]str = s.toCharArray();``    ``while` `(start <= end)``    ``{``        ` `        ``// Swapping the first and last character``        ``temp = str[start];``        ``str[start] = str[end];``        ``str[end] = temp;``        ``start++;``        ``end--;``    ``}``    ``return` `String.valueOf(str);``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``String arr[] = {``"aa"``, ``"ba"``, ``"ac"``};``    ``int` `cost[] = {``1``, ``3``, ``1``};``    ``int` `N = arr.length;` `    ``int` `res = minCost(arr, cost, N);``    ``if` `(res == -``1``)``        ``System.out.println(``"Sorting not possible\n"``);``    ``else``        ``System.out.println(``"Minimum cost to "` `+``                           ``"sort strings is "` `+ res);``    ``}``}` `// This code is contributed by Rajput-Ji`

## Python3

 `# Python program to get minimum cost to sort``# strings by reversal operation` `# Returns minimum cost for sorting arr[]``# using reverse operation. This function``# returns -1 if it is not possible to sort.``def` `ReverseStringMin(arr, reverseCost, n):``    ` `    ``# dp[i][j] represents the minimum cost to``    ``# make first i strings sorted.``    ``# j = 1 means i'th string is reversed.``    ``# j = 0 means i'th string is not reversed.``    ` `    ``dp ``=` `[[``float``(``"Inf"``)] ``*` `2` `for` `i ``in` `range``(n)]` `    ``# initializing dp array for first string``    ``dp[``0``][``0``] ``=` `0` `    ``dp[``0``][``1``] ``=` `reverseCost[``0``]` `    ``# getting array of reversed strings``    ``rev_arr ``=` `[i[::``-``1``] ``for` `i ``in` `arr]` `    ``# looping for all strings``    ``for` `i ``in` `range``(``1``, n):` `        ``# Looping twice, once for string and once``        ``# for reversed string``        ``for` `j ``in` `range``(``2``):` `            ``# getting current string and current``            ``# cost according to j``            ``curStr ``=` `arr[i] ``if` `j``=``=``0` `else` `rev_arr[i]` `            ``curCost ``=` `0` `if` `j``=``=``0` `else` `reverseCost[i]` `            ``# Update dp value only if current string``            ``# is lexicographically larger``            ``if` `(curStr >``=` `arr[i ``-` `1``]):` `                ``dp[i][j] ``=` `min``(dp[i][j], dp[i``-``1``][``0``] ``+` `curCost)` `            ``if` `(curStr >``=` `rev_arr[i ``-` `1``]):` `                ``dp[i][j] ``=` `min``(dp[i][j], dp[i``-``1``][``1``] ``+` `curCost)` `    ``# getting minimum from both entries of last index``    ``res ``=` `min``(dp[n``-``1``][``0``], dp[n``-``1``][``1``])` `    ``return` `res ``if` `res !``=` `float``(``"Inf"``) ``else` `-``1`  `# Driver code``def` `main():`  `    ``arr ``=` `[``"aa"``, ``"ba"``, ``"ac"``]` `    ``reverseCost ``=` `[``1``, ``3``, ``1``]` `    ``n ``=` `len``(arr)` `    ``dp ``=` `[``float``(``"Inf"``)] ``*` `n` `    ``res ``=` `ReverseStringMin(arr, reverseCost,n)` `    ``if` `res !``=` `-``1` `:` `        ``print` `(``"Minimum cost to sort sorting is"` `, res)` `    ``else` `:``        ``print` `(``"Sorting not possible"``)`  `if` `__name__ ``=``=` `'__main__'``:``    ``main()` `#This code is contributed by Neelam Yadav`

## C#

 `// C# program to get minimum cost to sort``// strings by reversal operation``using` `System;` `class` `GFG``{` `// Returns minimum cost for sorting arr[]``// using reverse operation. This function``// returns -1 if it is not possible to sort.``static` `int` `minCost(String []arr,``                   ``int` `[]cost, ``int` `N)``{``    ``// dp[i,j] represents the minimum cost to``    ``// make first i strings sorted.``    ``// j = 1 means i'th string is reversed.``    ``// j = 0 means i'th string is not reversed.``    ``int` `[,]dp = ``new` `int``[N, 2];` `    ``// initializing dp array for first string``    ``dp[0, 0] = 0;``    ``dp[0, 1] = cost;` `    ``// getting array of reversed strings``    ``String []revStr = ``new` `String[N];``    ``for` `(``int` `i = 0; i < N; i++)``    ``{``        ``revStr[i] = arr[i];``        ``revStr[i] = reverse(revStr[i], 0,``                            ``revStr[i].Length - 1);``    ``}` `    ``String curStr = ``""``;``    ``int` `curCost;` `    ``// looping for all strings``    ``for` `(``int` `i = 1; i < N; i++)``    ``{``        ``// Looping twice, once for string and once``        ``// for reversed string``        ``for` `(``int` `j = 0; j < 2; j++)``        ``{``            ``dp[i, j] = ``int``.MaxValue;` `            ``// getting current string and current``            ``// cost according to j``            ``curStr = (j == 0) ? arr[i] : revStr[i];``            ``curCost = (j == 0) ? 0 : cost[i];` `            ``// Update dp value only if current string``            ``// is lexicographically larger``            ``if` `(curStr.CompareTo(arr[i - 1]) >= 0)``                ``dp[i, j] = Math.Min(dp[i, j],``                                    ``dp[i - 1, 0] + curCost);``            ``if` `(curStr.CompareTo(revStr[i - 1]) >= 0)``                ``dp[i, j] = Math.Min(dp[i, j],``                                    ``dp[i - 1, 1] + curCost);``        ``}``    ``}` `    ``// getting minimum from both entries of last index``    ``int` `res = Math.Min(dp[N - 1, 0],``                       ``dp[N - 1, 1]);` `    ``return` `(res == ``int``.MaxValue) ? -1 : res;``}` `static` `String reverse(String s, ``int` `start, ``int` `end)``{` `    ``// Temporary variable to store character``    ``char` `temp;``    ``char` `[]str = s.ToCharArray();``    ``while` `(start <= end)``    ``{``        ` `        ``// Swapping the first and last character``        ``temp = str[start];``        ``str[start] = str[end];``        ``str[end] = temp;``        ``start++;``        ``end--;``    ``}``    ``return` `String.Join(``""``, str);``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{``    ``String []arr = {``"aa"``, ``"ba"``, ``"ac"``};``    ``int` `[]cost = {1, 3, 1};``    ``int` `N = arr.Length;` `    ``int` `res = minCost(arr, cost, N);``    ``if` `(res == -1)``        ``Console.WriteLine(``"Sorting not possible\n"``);``    ``else``        ``Console.WriteLine(``"Minimum cost to "` `+``                          ``"sort strings is "` `+ res);``    ``}``}` `// This code is contributed by Princi Singh`

## PHP

 `= ``\$arr``[``\$i` `- 1])``                ``\$dp``[``\$i``][``\$j``] = min(``\$dp``[``\$i``][``\$j``],``                                  ``\$dp``[``\$i` `- 1] +``                                  ``\$curCost``);``            ``if` `(``\$curStr` `>= ``\$revStr``[``\$i` `- 1])``                ``\$dp``[``\$i``][``\$j``] = min(``\$dp``[``\$i``][``\$j``],``                                  ``\$dp``[``\$i` `- 1] +``                                  ``\$curCost``);``        ``}``    ``}` `    ``// getting minimum from both entries``    ``// of last index``    ``\$res` `= min(``\$dp``[``\$N` `- 1], ``\$dp``[``\$N` `- 1]);` `    ``if``(``\$res` `== PHP_INT_MAX)``        ``return` `-1 ;``    ``else``        ``return` `\$res``;``}` `// Driver Code``\$arr` `= ``array``(``"aa"``, ``"ba"``, ``"ac"``);``\$cost` `= ``array``(1, 3, 1);``\$N` `= sizeof(``\$arr``);``\$res` `= minCost(``\$arr``, ``\$cost``, ``\$N``);``if` `(``\$res` `== -1)``    ``echo` `"Sorting not possible\n"``;``else``    ``echo` `"Minimum cost to sort strings is "` `. ``\$res``;` `// This code is contributed by ita_c``?>`

## Javascript

 ``

Output

`Minimum cost to sort strings is 1`

Time Complexity: O(N)
Auxiliary Space: O(N)

Efficient approach : Space Optimization O(1)

To optimize the space complexity of the above approach, we can eliminate the need for a 2D array dp and instead use variables to store the previous minimum costs. This will reduce the space complexity from O(N) to O(1).

Implementations Steps:

• Initialize dp0 as 0 and dp1 as the cost of the first string.
• Iterate from i = 1 to N-1, where N is the number of strings.
• Inside the loop, initialize cur0 and cur1 as INT_MAX.
• Compare arr[i] with arr[i-1] and update cur0 if arr[i] is larger or equal.
• Compare reversed arr[i] with arr[i-1] and update cur1 if it is larger or equal.
• Update dp0 with cur0 and dp1 with cur1.
• Get the minimum cost from dp0 and dp1 at the last index.
• If the minimum cost is still INT_MAX, return -1; otherwise, return the minimum cost.

Implementation:

## C++

 `#include ``using` `namespace` `std;` `// Returns minimum cost for sorting arr[]``// using reverse operation. This function``// returns -1 if it is not possible to sort.``int` `minCost(string arr[], ``int` `cost[], ``int` `N)``{``    ``int` `dp0 = 0; ``// Minimum cost for the previous string in original order``    ``int` `dp1 = cost; ``// Minimum cost for the previous string in reversed order` `    ``for` `(``int` `i = 1; i < N; i++)``    ``{``        ``int` `cur0 = INT_MAX; ``// Minimum cost for the current string in original order``        ``int` `cur1 = INT_MAX; ``// Minimum cost for the current string in reversed order` `        ``// Update dp values only if the current string is lexicographically larger``        ``if` `(arr[i] >= arr[i - 1])``            ``cur0 = min(cur0, dp0);``        ``if` `(arr[i] >= string(arr[i - 1].rbegin(), arr[i - 1].rend()))``            ``cur0 = min(cur0, dp1);` `        ``// Update dp values for reversed strings``        ``if` `(string(arr[i].rbegin(), arr[i].rend()) >= arr[i - 1])``            ``cur1 = min(cur1, dp0 + cost[i]);``        ``if` `(string(arr[i].rbegin(), arr[i].rend()) >= string(arr[i - 1].rbegin(), arr[i - 1].rend()))``            ``cur1 = min(cur1, dp1 + cost[i]);` `        ``dp0 = cur0; ``// Update the minimum cost for the previous string in original order``        ``dp1 = cur1; ``// Update the minimum cost for the previous string in reversed order``    ``}` `    ``// Get the minimum from both entries of the last index``    ``int` `res = min(dp0, dp1);` `    ``return` `(res == INT_MAX) ? -1 : res;``}` `// Driver code to test above methods``int` `main()``{``    ``string arr[] = {``"aa"``, ``"ba"``, ``"ac"``};``    ``int` `cost[] = {1, 3, 1};``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``int` `res = minCost(arr, cost, N);``    ``if` `(res == -1)``        ``cout << ``"Sorting not possible\n"``;``    ``else``        ``cout << ``"Minimum cost to sort strings is "` `<< res;` `    ``return` `0;``}`

Output

`Minimum cost to sort strings is 1`

Time Complexity: O(N)
Auxiliary Space: O(1)

This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

My Personal Notes arrow_drop_up