Number of pairs of String whose concatenation leads to a Sorted string
Last Updated :
04 Jan, 2023
Given an array of strings S with the size of N where each string contains at least two distinct characters. The task is to find the number of pairs of strings ( s[i], s[j] ) whose concatenation forms a string that is alphabetically sorted. Here concatenation is simply the process of appending one string after another.
Examples:
Input: S[] = {“aax”, “bbc”, “xz”}
Output: 2
Explanation: The pairs that form a sorted string when concatenated are: {“aax”, “xz”}, {“bbc”, “xz”}
Input: S[] = {“fg”, “mt”, “cd”}
Output: 3
Explanation: The pairs that form a sorted string when concatenated are: {“cd”, “fg”}, {“cd”, “mt”}, {“fg”, “mt”}
Naive Approach: The basic way to solve the problem is:
The brute force approach for this problem is to concatenate every pair of strings and then find out if the string formed is sorted or not.
Time complexity: O(N*N*max_size) where N is the size of the array of strings and max_size is the maximum size of the concatenation of two strings.
Auxiliary Space: O(1)
Efficient Approach: A better solution is based on these facts:
- If a string s1 is already unsorted and s2 is any random string then s1 + s2 will not form a sorted string.
- If the last character of a string s1 is lesser than or equal to the first character of another string s2 only then the string s1 + s2 can be sorted (provided both s1 and s2 are sorted).
Follow the below-mentioned steps to implement the above approach:
- Initialize a boolean array mark[] and label only those indexes as 1 for which s[i] is sorted and all other indexes as 0 (as to not consider them later).
- For each alphabet (a-z), calculate the number of sorted strings( mark[i] =1 ) that start with that particular alphabet and store the count in another array ( say nums ).
- For each string s[i], store the last character of that string in some last_char variable. A string that starts with an alphabet that comes after or equal to last_char can get appended to s[i] and it will always form a sorted string.
- Now iterate from the last_char till the last alphabet i.e. z and increment ans variable by the number of strings starting from each character involved in iteration.
- Return the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool sorted(string s)
{
for ( int i = 0; i < s.size() - 1; i++) {
if (s[i] > s[i + 1])
return false ;
}
return 1;
}
int solve(string S[], int N)
{
bool mark[N + 1] = { 0 };
for ( int i = 0; i < N; i++) {
if (sorted(S[i])) {
mark[i] = 1;
}
}
int nums[26] = { 0 };
for ( int i = 0; i < N; i++) {
if (mark[i] == 1) {
int p = S[i][0] - 'a' ;
nums[p] += 1;
}
}
int ans = 0;
for ( int i = 0; i < N; i++) {
if (mark[i] == 1) {
int len = S[i].size();
int last_char = S[i][len - 1] - 'a' ;
for ( int j = last_char; j < 26; j++) {
ans += nums[j];
}
}
}
return ans;
}
int main()
{
string S[] = { "ac" , "df" , "pzz" };
int N = sizeof (S) / sizeof (S[0]);
cout << solve(S, N) << endl;
string S2[] = { "pqrs" , "amq" , "bcd" };
N = sizeof (S2) / sizeof (S2[0]);
cout << solve(S2, N) << endl;
return 0;
}
|
Java
import java.util.Arrays;
public class Main {
static boolean sorted(String s)
{
for ( int i = 0 ; i < s.length() - 1 ; i++) {
if (s.charAt(i) > s.charAt(i + 1 )) {
return false ;
}
}
return true ;
}
static int solve(String[] S, int N)
{
boolean [] mark = new boolean [N + 1 ];
Arrays.fill(mark, false );
for ( int i = 0 ; i < N; i++) {
if (sorted(S[i])) {
mark[i] = true ;
}
}
int [] nums = new int [ 26 ];
Arrays.fill(nums, 0 );
for ( int i = 0 ; i < N; i++) {
if (mark[i]) {
int p = S[i].charAt( 0 ) - 'a' ;
nums[p] += 1 ;
}
}
int ans = 0 ;
for ( int i = 0 ; i < N; i++) {
if (mark[i]) {
int len = S[i].length();
int lastChar = S[i].charAt(len - 1 ) - 'a' ;
for ( int j = lastChar; j < 26 ; j++) {
ans += nums[j];
}
}
}
return ans;
}
public static void main(String[] args)
{
String[] S = { "ac" , "df" , "pzz" };
int N = S.length;
System.out.println(solve(S, N));
String[] S2 = { "pqrs" , "amq" , "bcd" };
N = S2.length;
System.out.println(solve(S2, N));
}
}
|
Python3
def sorted (s):
for i in range ( len (s) - 1 ):
if s[i] > s[i + 1 ]:
return False
return True
def solve(S, N):
mark = [ False ] * (N + 1 )
for i in range (N):
if sorted (S[i]):
mark[i] = True
nums = [ 0 ] * 26
for i in range (N):
if mark[i]:
p = ord (S[i][ 0 ]) - ord ( 'a' )
nums[p] + = 1
ans = 0
for i in range (N):
if mark[i]:
Len = len (S[i])
lastChar = ord (S[i][ Len - 1 ]) - ord ( 'a' )
for j in range (lastChar, 26 ):
ans + = nums[j]
return ans
S = [ "ac" , "df" , "pzz" ]
N = len (S)
print (solve(S, N))
S2 = [ "pqrs" , "amq" , "bcd" ]
N = len (S2)
print (solve(S2, N))
|
C#
using System;
public class GFG {
static bool sorted( string s)
{
for ( int i = 0; i < s.Length - 1; i++) {
if (s[i] > s[i + 1]) {
return false ;
}
}
return true ;
}
static int solve( string [] S, int N)
{
bool [] mark = new bool [N + 1];
for ( int i = 0; i < N + 1; i++) {
mark[i] = false ;
}
for ( int i = 0; i < N; i++) {
if (sorted(S[i])) {
mark[i] = true ;
}
}
int [] nums = new int [26];
for ( int i = 0; i < 26; i++) {
nums[i] = 0;
}
for ( int i = 0; i < N; i++) {
if (mark[i]) {
int p = ( int )S[i][0] - ( int ) 'a' ;
nums[p] += 1;
}
}
int ans = 0;
for ( int i = 0; i < N; i++) {
if (mark[i]) {
int len = S[i].Length;
int lastChar
= ( int )S[i][len - 1] - ( int ) 'a' ;
for ( int j = lastChar; j < 26; j++) {
ans += nums[j];
}
}
}
return ans;
}
static public void Main()
{
string [] S = { "ac" , "df" , "pzz" };
int N = S.Length;
Console.WriteLine(solve(S, N));
string [] S2 = { "pqrs" , "amq" , "bcd" };
N = S2.Length;
Console.WriteLine(solve(S2, N));
}
}
|
Javascript
function sorted(s) {
for (let i = 0; i < s.length - 1; i++) {
if (s[i] > s[i + 1]) return false ;
}
return true ;
}
function solve(S, N) {
const mark = new Array(N + 1).fill( false );
for (let i = 0; i < N; i++) {
if (sorted(S[i])) {
mark[i] = true ;
}
}
const nums = new Array(26).fill(0);
for (let i = 0; i < N; i++) {
if (mark[i]) {
const p = S[i][0].charCodeAt(0) - 'a' .charCodeAt(0);
nums[p] += 1;
}
}
let ans = 0;
for (let i = 0; i < N; i++) {
if (mark[i]) {
const len = S[i].length;
const lastChar = S[i][len - 1].charCodeAt(0) - 'a' .charCodeAt(0);
for (let j = lastChar; j < 26; j++) {
ans += nums[j];
}
}
}
return ans;
}
let S = [ "ac" , "df" , "pzz" ];
let N = S.length;
console.log(solve(S, N));
let S2 = [ "pqrs" , "amq" , "bcd" ];
N = S2.length;
console.log(solve(S2, N));
|
Time Complexity: O(N*MAX_SIZE), MAX_SIZE is the length of longest string
Auxiliary Space: O(N)
Related Articles:
Share your thoughts in the comments
Please Login to comment...