Given a string find the number of unique permutations that can be obtained by swapping two indices such that the elements at these indices are distinct.
NOTE: Swapping is always performed in the original string.
Examples:
Input: str = “sstt”
Output: 5
Explanation:
Swap str[0] with str[2], string obtained “tsst” which is valid (str[0]!=str[2])
Swap str[0] with str[3]. string obtained “tsts”
Swap str[1] with str[2], string obtained “stst”
Swap str[1] with str[3], string obtained “stts”
Hence total 5 strings can be obtained including the given string (“sstt”)Input: str = “abcd”
Output: 7
Naive Approach:
- Create a set to store unique strings
- Loop through each pair of indices in the given string
- Check if the elements at the pair of indices are distinct
- If the elements are distinct, swap the elements at those indices and add the resulting string to the set
- Swap the elements back to their original positions
- Add 1 to count the original string
- Return the number of unique permutations, including the original string.
Below is the implementation of the above approach:
C++
#include <iostream>#include <set>#include <string>using namespace std;int countUniquePermutations(string str){ // create a set to store unique strings set<string> uniqueStrings; // loop through each pair of indices // in the given string for (int i = 0; i < str.length(); i++) { for (int j = i + 1; j < str.length(); j++) { // check if the elements at the // pair of indices are distinct if (str[i] != str[j]) { swap(str[i], str[j]); uniqueStrings.insert(str); swap(str[i], str[j]); } } } // add 1 to count the original string // and return number of unique permutations return uniqueStrings.size() + 1;}int main(){ string str = "sstt"; cout << countUniquePermutations(str); return 0;} |
Java
import java.util.HashSet;import java.util.Set;public class UniquePermutations { public static int countUniquePermutations(String str) { // Create a set to store unique strings Set<String> uniqueStrings = new HashSet<>(); // Loop through each pair of indices in the given // string for (int i = 0; i < str.length(); i++) { for (int j = i + 1; j < str.length(); j++) { // Check if the elements at the pair of // indices are distinct if (str.charAt(i) != str.charAt(j)) { // Swap the characters at the indices char[] strArray = str.toCharArray(); char temp = strArray[i]; strArray[i] = strArray[j]; strArray[j] = temp; String swappedStr = new String(strArray); // Add the swapped string to the set uniqueStrings.add(swappedStr); // Swap back to the original string temp = strArray[i]; strArray[i] = strArray[j]; strArray[j] = temp; } } } // Add 1 to count the original string and return the // number of unique permutations return uniqueStrings.size() + 1; } public static void main(String[] args) { String str = "sstt"; System.out.println(countUniquePermutations(str)); }} |
Python3
def count_unique_permutations(s): # Create a set to store unique strings unique_strings = set() # Loop through each pair of indices in the given string for i in range(len(s)): for j in range(i + 1, len(s)): # Check if the elements at the pair of indices are distinct if s[i] != s[j]: # Swap the elements at the indices to generate a new string # and add it to the set s_list = list(s) s_list[i], s_list[j] = s_list[j], s_list[i] unique_strings.add("".join(s_list)) # Add 1 to count the original string and return the number of unique permutations return len(unique_strings) + 1# Driver Codeif __name__ == "__main__": input_str = "sstt" print(count_unique_permutations(input_str)) |
C#
using System;using System.Collections.Generic;class Program{ static int CountUniquePermutations(string str) { // Create a HashSet to store unique strings HashSet<string> uniqueStrings = new HashSet<string>(); // Loop through each pair of indices in the given string for (int i = 0; i < str.Length; i++) { for (int j = i + 1; j < str.Length; j++) { // Check if the elements at the pair of indices are distinct if (str[i] != str[j]) { char[] chars = str.ToCharArray(); // Swap the elements at indices i and j char temp = chars[i]; chars[i] = chars[j]; chars[j] = temp; string newString = new string(chars); // Insert the unique string into the HashSet uniqueStrings.Add(newString); // Swap back to restore the original string temp = chars[i]; chars[i] = chars[j]; chars[j] = temp; } } } // Add 1 to count the original string and return the number of unique permutations return uniqueStrings.Count + 1; } static void Main() { string str = "sstt"; Console.WriteLine(CountUniquePermutations(str)); }} |
Javascript
function countUniquePermutations(str) { // Create a Set to store unique strings let uniqueStrings = new Set(); // Loop through each pair of indices in the given string for (let i = 0; i < str.length; i++) { for (let j = i + 1; j < str.length; j++) { // Check if the elements at the pair of indices are distinct if (str[i] !== str[j]) { // Swap the characters at indices i and j let strArray = str.split(''); [strArray[i], strArray[j]] = [strArray[j], strArray[i]]; let modifiedStr = strArray.join(''); uniqueStrings.add(modifiedStr); // Swap the characters back to their original positions [strArray[i], strArray[j]] = [strArray[j], strArray[i]]; } } } // Add 1 to count the original string and return the number of unique permutations return uniqueStrings.size + 1;}let str = "sstt";console.log(countUniquePermutations(str)); |
5
Time Complexity: The time complexity of this algorithm is O(n2 * log n), where n is the length of the input string. This is because we have two nested loops, and within each loop, we perform a constant-time set insertion operation, which has a time complexity of O(log n) on average. Therefore, the overall time complexity is O(n^2 * log n).
Auxiliary Space: The space complexity of this algorithm is also O(n2). This is because we create a set to store the unique strings, and the size of the set can be as large as n^2 in the worst case, if all possible string permutations are unique. Additionally, we store the input string itself, which has a size of n. Therefore, the overall space complexity is O(n^2 + n), which simplifies to O(n^2).
Efficient Approach: The problem can be solved using HashMap by the following steps:
- Create a hashmap and store the frequency of every character of the given string.
- Create a variable count, to store the total number of characters in the given string, i.e. count=str.length() and a variable ans to store the number of unique permutations possible and initialize ans=0.
- Traverse the string and for each character:
- Find the number of different characters present in the right of the current index. This can be done by subtracting the frequency of that character by the total count.
- Now add this calculated value to ans, as this is the number of characters with which the current character can be swapped to create a unique permutation.
- Now, Reduce the frequency of the current character and count by 1, so that it cannot interfere with the calculations of the same elements present to the right of it.
- Return ans+1, because the given string is also a unique permutation.
C++
// C++ program for the above approach#include <bits/stdc++.h>using namespace std;// Function to calculate total// number of valid permutationsint validPermutations(string str){ unordered_map<char, int> m; // Creating count which is equal to the // Total number of characters present and // ans that will store the number of unique // permutations int count = str.length(), ans = 0; // Storing frequency of each character // present in the string for (int i = 0; i < str.length(); i++) { m[str[i]]++; } for (int i = 0; i < str.length(); i++) { // Adding count of characters by excluding // characters equal to current char ans += count - m[str[i]]; // Reduce the frequency of the current character // and count by 1, so that it cannot interfere // with the calculations of the same elements // present to the right of it. m[str[i]]--; count--; } // Return ans+1 (Because the given string // is also a unique permutation) return ans + 1;}// Driver Codeint main(){ string str = "sstt"; cout << validPermutations(str); return 0;} |
Java
// Java program for the above approach// Importing HashMap classimport java.util.HashMap;class GFG { // Function to calculate total // number of valid permutations static int validPermutations(String str) { HashMap<Character, Integer> m = new HashMap<Character, Integer>(); // Creating count which is equal to the // Total number of characters present and // ans that will store the number of unique // permutations int count = str.length(), ans = 0; // Storing frequency of each character // present in the string for (int i = 0; i < str.length(); i++) { m.put(str.charAt(i), m.getOrDefault(str.charAt(i), 0) + 1); } for (int i = 0; i < str.length(); i++) { // Adding count of characters by excluding // characters equal to current char ans += count - m.get(str.charAt(i)); // Reduce the frequency of the current character // and count by 1, so that it cannot interfere // with the calculations of the same elements // present to the right of it. m.put(str.charAt(i), m.get(str.charAt(i)) - 1); count--; } // Return ans+1 (Because the given string // is also a unique permutation) return ans + 1; } public static void main(String[] args) { String str = "sstt"; System.out.println(validPermutations(str)); }}// This code is contributed by rajsanghavi9. |
Python3
# Python 3 program for the above approach# Function to calculate total# number of valid permutationsdef validPermutations(str): m = {} # Creating count which is equal to the # Total number of characters present and # ans that will store the number of unique # permutations count = len(str) ans = 0 # Storing frequency of each character # present in the string for i in range(len(str)): if(str[i] in m): m[str[i]] += 1 else: m[str[i]] = 1 for i in range(len(str)): # Adding count of characters by excluding # characters equal to current char ans += count - m[str[i]] # Reduce the frequency of the current character # and count by 1, so that it cannot interfere # with the calculations of the same elements # present to the right of it. m[str[i]] -= 1 count -= 1 # Return ans+1 (Because the given string # is also a unique permutation) return ans + 1# Driver Codeif __name__ == '__main__': str = "sstt" print(validPermutations(str)) # This code is contributed by SURENDRA_GANGWAR. |
C#
// C# program for the above approach// Importing Dictionary classusing System;using System.Collections.Generic;public class GFG { // Function to calculate total // number of valid permutations static int validPermutations(String str) { Dictionary<char, int> m = new Dictionary<char, int>(); // Creating count which is equal to the // Total number of characters present and // ans that will store the number of unique // permutations int count = str.Length, ans = 0; // Storing frequency of each character // present in the string for (int i = 0; i < str.Length; i++) { if(m.ContainsKey(str[i])) m[str[i]]=m[str[i]]+1; else m.Add(str[i], 1); } for (int i = 0; i < str.Length; i++) { // Adding count of characters by excluding // characters equal to current char ans += count - m[str[i]]; // Reduce the frequency of the current character // and count by 1, so that it cannot interfere // with the calculations of the same elements // present to the right of it. if(m.ContainsKey(str[i])) m[str[i]]=m[str[i]]-1; count--; } // Return ans+1 (Because the given string // is also a unique permutation) return ans + 1; } public static void Main(String[] args) { String str = "sstt"; Console.WriteLine(validPermutations(str)); }}// This code is contributed by shikhasingrajput |
Javascript
<script>// JavaScript program for the above approach// Function to calculate total// number of valid permutationsfunction validPermutations(str) { let m = new Map(); // Creating count which is equal to the // Total number of characters present and // ans that will store the number of unique // permutations let count = str.length, ans = 0; // Storing frequency of each character // present in the string for (let i = 0; i < str.length; i++) { if (m.has(str[i])) { m.set(str[i], m.get(str[i]) + 1); } else { m.set(str[i], 1); } } for (let i = 0; i < str.length; i++) { // Adding count of characters by excluding // characters equal to current char ans += count - m.get(str[i]); // Reduce the frequency of the current character // and count by 1, so that it cannot interfere // with the calculations of the same elements // present to the right of it. m.set(str[i], m.get(str[i]) - 1); count--; } // Return ans+1 (Because the given string // is also a unique permutation) return ans + 1;}// Driver Codelet str = "sstt";document.write(validPermutations(str));</script> |
5
Time Complexity: O(n)
Auxiliary Space: O(n)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
