Given a string s, return a string containing all distinct characters from s in non-decreasing order, without using any sorting algorithm.
Examples:
Input: s = "abdbc"
Output: "abcd"
Explanation: The distinct characters in s are 'a', 'b', 'd', and 'c'. When sorted, they form "abcd".Input: s = "fdfdfd"
Output: "df"
Explanation: The distinct characters in s are 'f' and 'd'. When sorted, they form "df".
Table of Content
[Naive Approach] - Iterating Over All Characters
Since the characters are lowercase English letters, check each character from
'a'to'z'and add it to the answer if it appears in the string.
- Initialize an empty result string.
- Traverse all characters from 'a' to 'z'.
- For each character, scan the entire string.
- If the character is found, append it to the result and stop scanning for that character.
- Return the resulting string.
#include <bits/stdc++.h>
using namespace std;
string sortedDistinct(string &s) {
string ans = "";
// Check every lowercase character
for (char ch = 'a'; ch <= 'z'; ch++) {
// Search the current character in the string
for (int i = 0; i < s.length(); i++) {
if (s[i] == ch) {
ans += ch;
break;
}
}
}
return ans;
}
int main() {
string s = "abdbc";
cout << sortedDistinct(s);
return 0;
}
import java.util.*;
public class GFG {
public static String sortedDistinct(String s) {
String ans = "";
// Check every lowercase character
for (char ch = 'a'; ch <= 'z'; ch++) {
// Search the current character in the string
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ch) {
ans += ch;
break;
}
}
}
return ans;
}
public static void main(String[] args) {
String s = "abdbc";
System.out.println(sortedDistinct(s));
}
}
def sortedDistinct(s):
ans = ""
# Check every lowercase character
for ch in range(ord('a'), ord('z') + 1):
ch = chr(ch)
# Search the current character in the string
if ch in s:
ans += ch
return ans
if __name__ == '__main__':
s = "abdbc"
print(sortedDistinct(s))
using System;
public class GFG {
public static string sortedDistinct(string s) {
string ans = "";
// Check every lowercase character
for (char ch = 'a'; ch <= 'z'; ch++) {
// Search the current character in the string
for (int i = 0; i < s.Length; i++) {
if (s[i] == ch) {
ans += ch;
break;
}
}
}
return ans;
}
public static void Main() {
string s = "abdbc";
Console.WriteLine(sortedDistinct(s));
}
}
function sortedDistinct(s) {
let ans = "";
// Check every lowercase character
for (let ch = 'a'.charCodeAt(0); ch <= 'z'.charCodeAt(0); ch++) {
let char = String.fromCharCode(ch);
// Search the current character in the string
if (s.includes(char)) {
ans += char;
}
}
return ans;
}
// Driver code
let s = "abdbc";
console.log(sortedDistinct(s));
Output
abcd
Time Complexity: O(n*26) , as the string is scanned once for each of the 26 lowercase letters.
Space Complexity: O(1)
[Better Approach] - Using Hash Set
Use a set to automatically remove duplicate characters and keep them in sorted order.
- Create an empty set of characters.
- Traverse the string and insert each character into the set.
- Initialize an empty result string.
- Traverse the set and append each character to the result.
- Return the resulting string.
Note: This approach uses a sorted set, which is available as set in C++, TreeSet in Java, and SortedSet<T> in C#. Languages like Python and JavaScript do not have a built-in sorted set, so this approach cannot be implemented directly using their standard libraries.
#include <bits/stdc++.h>
using namespace std;
string sortedDistinct(string &s) {
// Set stores only distinct characters in sorted order
set<char> st;
// Insert all characters into the set
for (int i = 0; i < s.length(); i++) {
st.insert(s[i]);
}
string ans = "";
// Build the answer from the sorted set
for (auto x : st) {
ans += x;
}
return ans;
}
int main() {
string s = "abdbc";
cout << sortedDistinct(s);
return 0;
}
import java.util.*;
public class GFG {
static String sortedDistinct(String s) {
// TreeSet stores only distinct characters in sorted order
TreeSet<Character> set = new TreeSet<>();
// Insert all characters into the set
for (int i = 0; i < s.length(); i++) {
set.add(s.charAt(i));
}
StringBuilder ans = new StringBuilder();
// Build the answer from the sorted set
for (char ch : set) {
ans.append(ch);
}
return ans.toString();
}
public static void main(String[] args) {
String s = "abdbc";
System.out.println(sortedDistinct(s));
}
}
def sortedDistinct(s):
st = set()
# Insert all characters into the set
for ch in s:
st.add(ch)
ans = ""
# Check every lowercase character
for ch in range(ord('a'), ord('z') + 1):
if chr(ch) in st:
ans += chr(ch)
return ans
if __name__ == "__main__":
s = "abdbc"
print(sortedDistinct(s))
using System;
using System.Collections.Generic;
class GFG {
static string sortedDistinct(string s) {
// SortedSet stores only distinct characters in sorted order
SortedSet<char> set = new SortedSet<char>();
// Insert all characters into the set
foreach (char ch in s) {
set.Add(ch);
}
string ans = "";
// Build the answer from the sorted set
foreach (char ch in set) {
ans += ch;
}
return ans;
}
static void Main() {
string s = "abdbc";
Console.WriteLine(SortedDistinct(s));
}
}
function sortedDistinct(s) {
// Set stores only distinct characters
let st = new Set();
// Insert all characters into the set
for (let i = 0; i < s.length; i++) {
st.add(s[i]);
}
let ans = "";
// Check every lowercase character
for (let ch = 97; ch <= 122; ch++) {
let c = String.fromCharCode(ch);
if (st.has(c)) {
ans += c;
}
}
return ans;
}
// Driver code
let s = "abdbc";
console.log(sortedDistinct(s));
Output
abcd
Time Complexity: O(n*log n) in general, as each insertion into the set takes O(log n). However, since the set can contain at most 26 lowercase characters, each insertion takes O(log 26) = O(1). Hence, the overall time complexity becomes O(n).
Space Complexity: O(n) in general, but since the set can contain at most 26 characters, it becomes O(26) = O(1).
[Expected Approach] - Frequency Array - O(n) Time and O(1) Space
The idea is to mark the occurrence of every character using a frequency array of size 26. Then, traverse the array from 'a' to 'z' and append every character whose frequency is non-zero to the result string. Since the characters are processed in alphabetical order, the output is already sorted.
Working of Approach:
- Create a boolean array of size 26 to mark the presence of each lowercase character.
- Traverse the string and mark the corresponding index for every character as true.
- Traverse the boolean array from index 0 to 25, corresponding to characters 'a' to 'z'.
- Append every marked character to the result string.
- Return the resulting string containing all distinct characters in sorted order.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
string sortedDistinct(string &s)
{
// Marks the presence of each character
vector<bool> vis(26, false);
// Mark all characters present in the string
for (char ch : s)
vis[ch - 'a'] = true;
string res = "";
// Build the result string in sorted order
for (int i = 0; i < 26; i++)
{
if (vis[i])
res += char(i + 'a');
}
return res;
}
int main()
{
string s = "fdfdfd";
cout << "\"" << sortedDistinct(s) << "\"";
return 0;
}
import java.util.*;
public class Main {
// Marks the presence of each character
static String sortedDistinct(String s) {
boolean[] vis = new boolean[26];
// Mark all characters present in the string
for (char ch : s.toCharArray())
vis[ch - 'a'] = true;
String res = "";
// Build the result string in sorted order
for (int i = 0; i < 26; i++)
{
if (vis[i])
res += (char)(i + 'a');
}
return res;
}
public static void main(String[] args) {
String s = "fdfdfd";
System.out.println("\"" + sortedDistinct(s) + "\"");
}
}
def sortedDistinct(s):
# Marks the presence of each character
vis = [False] * 26
# Mark all characters present in the string
for ch in s:
vis[ord(ch) - ord('a')] = True
res = ""
# Build the result string in sorted order
for i in range(26):
if vis[i]:
res += chr(i + ord('a'))
return res
if __name__ == "__main__":
s = "fdfdfd"
print("\"" + sortedDistinct(s) + "\"")
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
// Marks the presence of each character
static string sortedDistinct(string s)
{
bool[] vis = new bool[26];
// Mark all characters present in the string
foreach (char ch in s)
vis[ch - 'a'] = true;
string res = "";
// Build the result string in sorted order
for (int i = 0; i < 26; i++)
{
if (vis[i])
res += (char)(i + 'a');
}
return res;
}
static void Main()
{
string s = "fdfdfd";
Console.WriteLine("\"" + sortedDistinct(s) + "\"");
}
}
function sortedDistinct(s)
{
// Marks the presence of each character
let vis = Array(26).fill(false);
// Mark all characters present in the string
for (let ch of s) {
vis[ch.charCodeAt(0) - "a".charCodeAt(0)] = true;
}
let res = "";
// Build the result string in sorted order
for (let i = 0; i < 26; i++) {
if (vis[i]) {
res += String.fromCharCode(i
+ "a".charCodeAt(0));
}
}
return res;
}
// Driver Code
let s = "fdfdfd";
console.log(`\"${sortedDistinct(s)}\"`);
Output
"df"