Open In App

Number of pairs of String whose concatenation leads to a Sorted string

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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++
// C++ implementation of program
#include <bits/stdc++.h>
using namespace std;

// Check if a particular string is
// sorted or not
bool sorted(string s)
{

    for (int i = 0; i < s.size() - 1; i++) {
        if (s[i] > s[i + 1])
            return false;
    }
    return 1;
}

// Function to find the required
// number of pairs
int solve(string S[], int N)
{

    // Boolean array mark to consider only
    // those strings which are sorted and
    // reject those which are not sorted
    bool mark[N + 1] = { 0 };

    for (int i = 0; i < N; i++) {
        if (sorted(S[i])) {
            mark[i] = 1;
        }
    }
    // For every lower_case alphabet find out
    // how many strings start with that
    // particular alphabet
    int nums[26] = { 0 };

    for (int i = 0; i < N; i++) {

        if (mark[i] == 1) {
            int p = S[i][0] - 'a';
            nums[p] += 1;
        }
    }

    // Compute the answer for all
    // the sorted strings
    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 the answer
    return ans;
}

// Driver Code
int main()
{

    // Test case 1
    string S[] = { "ac", "df", "pzz" };
    int N = sizeof(S) / sizeof(S[0]);

    // Function call
    cout << solve(S, N) << endl;

    // Test case 2
    string S2[] = { "pqrs", "amq", "bcd" };
    N = sizeof(S2) / sizeof(S2[0]);

    // Function call
    cout << solve(S2, N) << endl;
    return 0;
}
Java
// Java code for the above approach
import java.util.Arrays;

public class Main {

    // Check if a particular string is
    // sorted or not
    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;
    }

    // Function to find the required
    // number of pairs
    static int solve(String[] S, int N)
    {
        // Boolean array mark to consider only
        // those strings which are sorted and
        // reject those which are not sorted
        boolean[] mark = new boolean[N + 1];
        Arrays.fill(mark, false);

        for (int i = 0; i < N; i++) {
            if (sorted(S[i])) {
                mark[i] = true;
            }
        }
        // For every lower_case alphabet find out
        // how many strings start with that
        // particular alphabet
        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;
            }
        }

        // Compute the answer for all
        // the sorted strings
        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 the answer
        return ans;
    }

    // Driver code
    public static void main(String[] args)
    {
        // Test case 1
        String[] S = { "ac", "df", "pzz" };
        int N = S.length;

        // Function call
        System.out.println(solve(S, N));

        // Test case 2
        String[] S2 = { "pqrs", "amq", "bcd" };
        N = S2.length;

        // Function call
        System.out.println(solve(S2, N));
    }
}
// This code is contributed by Potta Lokesh
Python3
# Python code for the above approach

# Check if a particular string is
# sorted or not
def sorted(s):
    for i in range(len(s) - 1):
        if s[i] > s[i + 1]:
            return False
    return True

# Function to find the required
# number of pairs
def solve(S, N):
    # Boolean array mark to consider only
    # those strings which are sorted and
    # reject those which are not sorted
    mark = [False] * (N + 1)
    for i in range(N):
        if sorted(S[i]):
            mark[i] = True

    # For every lower_case alphabet find out
    # how many strings start with that
    # particular alphabet
    nums = [0] * 26
    for i in range(N):
        if mark[i]:
            p = ord(S[i][0]) - ord('a')
            nums[p] += 1

    # Compute the answer for all
    # the sorted strings
    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 the answer
    return ans


# Test case 1
S = ["ac", "df", "pzz"]
N = len(S)

# Function call
print(solve(S, N))

# Test case 2
S2 = ["pqrs", "amq", "bcd"]
N = len(S2)

# Function call
print(solve(S2, N))

# This code is contributed by lokeshmvs21.
C#
// C# code for the above approach
using System;

public class GFG {

  // Check if a particular string is
  // sorted or not
  static bool sorted(string s)
  {
    for (int i = 0; i < s.Length - 1; i++) {
      if (s[i] > s[i + 1]) {
        return false;
      }
    }
    return true;
  }

  // Function to find the required
  // number of pairs
  static int solve(string[] S, int N)
  {
    // Boolean array mark to consider only
    // those strings which are sorted and
    // reject those which are not sorted
    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;
      }
    }
    // For every lower_case alphabet find out
    // how many strings start with that
    // particular alphabet
    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;
      }
    }

    // Compute the answer for all
    // the sorted strings
    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 the answer
    return ans;
  }

  static public void Main()
  {

    // Code
    // Test case 1
    string[] S = { "ac", "df", "pzz" };
    int N = S.Length;

    // Function call
    Console.WriteLine(solve(S, N));

    // Test case 2
    string[] S2 = { "pqrs", "amq", "bcd" };
    N = S2.Length;

    // Function call
    Console.WriteLine(solve(S2, N));
  }
}

// This code is contributed by lokesh.
JavaScript
// Check if a particular string is
// sorted or not
function sorted(s) {
  for (let i = 0; i < s.length - 1; i++) {
    if (s[i] > s[i + 1]) return false;
  }
  return true;
}

// Function to find the required
// number of pairs
function solve(S, N) {
   // Boolean array mark to consider only
    // those strings which are sorted and
    // reject those which are not sorted
  const mark = new Array(N + 1).fill(false);
  for (let i = 0; i < N; i++) {
    if (sorted(S[i])) {
      mark[i] = true;
    }
  }
  // For every lower_case alphabet find out
    // how many strings start with that
    // particular alphabet
  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;
    }
  }
  // Compute the answer for all the sorted strings.
  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 the answer.
  return ans;
}

 // Test case 1
 let S = [ "ac", "df", "pzz" ];
 let N = S.length;

 // Function call
 console.log(solve(S, N));

 // Test case 2
 let S2 = [ "pqrs", "amq", "bcd" ];
 N = S2.length;

 // Function call
 console.log(solve(S2, N));

//  This code is contributed by akashish__

Output
3
1

Time Complexity: O(N*MAX_SIZE), MAX_SIZE is the length of longest string
Auxiliary Space: O(N)

Related Articles: 


Similar Reads