Given two strings S1 and S2. The task is to concatenate uncommon characters of the S2 to S1 and return the resultant string S1 .
Examples:
Input: S1 = “aacdb”, S2 = “gafd”
Output: “cbgf”
Input: S1 = “abcs”, S2 = “cxzca”;
Output: “bsxz”
Method 1: Using Hashmap
Approach:
Below is the idea to solve the problem.
The idea is to use Hashmap where the key is a character and the value is an integer i.e. number of strings in which the character is present. If a character is present in one string, then the count is 1, else if the character is present in both strings, the count is 2.
Follow the steps below to implement the idea:
- Initialize the result as an empty string.
- Push all characters of S2 string in map with count as 1.
- Traverse first string and append all those characters to result that are not present in map then make their count 2.
- Traverse second string and append all those characters to result whose count is 1.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
string concatenatedString(string s1, string s2)
{
string res = "" ;
unordered_map< char , int > m;
for ( int i = 0; i < s2.size(); i++)
m[s2[i]] = 1;
for ( int i = 0; i < s1.size(); i++) {
if (m.find(s1[i]) == m.end())
res += s1[i];
else
m[s1[i]] = 2;
}
for ( int i = 0; i < s2.size(); i++)
if (m[s2[i]] == 1)
res += s2[i];
return res;
}
int main()
{
string s1 = "abcs" ;
string s2 = "cxzca" ;
cout << concatenatedString(s1, s2);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class gfg {
public static String concatenatedString(String s1,
String s2)
{
String res = "" ;
int i;
HashMap<Character, Integer> m
= new HashMap<Character, Integer>();
for (i = 0 ; i < s2.length(); i++)
m.put(s2.charAt(i), 1 );
for (i = 0 ; i < s1.length(); i++)
if (!m.containsKey(s1.charAt(i)))
res += s1.charAt(i);
else
m.put(s1.charAt(i), 2 );
for (i = 0 ; i < s2.length(); i++)
if (m.get(s2.charAt(i)) == 1 )
res += s2.charAt(i);
return res;
}
public static void main(String[] args)
{
String s1 = "abcs" ;
String s2 = "cxzca" ;
System.out.println(concatenatedString(s1, s2));
}
}
|
Python 3
def concatenatedString(s1, s2):
res = ""
m = {}
for i in range ( 0 , len (s2)):
m[s2[i]] = 1
for i in range ( 0 , len (s1)):
if ( not s1[i] in m):
res = res + s1[i]
else :
m[s1[i]] = 2
for i in range ( 0 , len (s2)):
if (m[s2[i]] = = 1 ):
res = res + s2[i]
return res
if __name__ = = "__main__" :
s1 = "abcs"
s2 = "cxzca"
print (concatenatedString(s1, s2))
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static String concatenatedString(String s1,
String s2)
{
String res = "" ;
int i;
Dictionary< char , int > m
= new Dictionary< char , int >();
for (i = 0; i < s2.Length; i++)
if (!m.ContainsKey(s2[i]))
m.Add(s2[i], 1);
for (i = 0; i < s1.Length; i++)
if (!m.ContainsKey(s1[i]))
res += s1[i];
else
m[s1[i]] = 2;
for (i = 0; i < s2.Length; i++)
if (m[s2[i]] == 1)
res += s2[i];
return res;
}
public static void Main(String[] args)
{
String s1 = "abcs" ;
String s2 = "cxzca" ;
Console.WriteLine(concatenatedString(s1, s2));
}
}
|
Javascript
<script>
function concatenatedString(s1, s2)
{
let res = "" ;
let m = new Map();
for (let i = 0; i < s2.length; i++)
m.set(s2[i],1);
for (let i = 0; i < s1.length; i++) {
if (m.has(s1[i]) == false )
res += s1[i];
else
m.set(s1[i] , 2);
}
for (let i = 0; i < s2.length; i++)
if (m.get(s2[i]) == 1)
res += s2[i];
return res;
}
let s1 = "abcs" ;
let s2 = "cxzca" ;
document.write(concatenetedString(s1, s2));
</script>
|
Time Complexity: O(M + N), where M and N represents the size of the given two strings.
Auxiliary Space: O(max(M, N)), where M and N represents the size of the given two strings.
Method 2: Using Set
Use a set instead of a hashmap to store the characters of the second string. This can simplify the code and reduce the space complexity.
Approach:
- Initialize the result as an empty string.
- Add all characters of S2 string in a set.
- Traverse S1 string and append all those characters to result that are not present in the set.
- Return the result.
Below is the implementation of the updated approach:
C++
#include <bits/stdc++.h>
using namespace std;
string concatenatedString(string s1, string s2)
{
string res = "" ;
unordered_set< char > s(s2.begin(), s2.end());
for ( int i = 0; i < s1.size(); i++) {
if (s.find(s1[i]) == s.end())
res += s1[i];
else
s.erase(s1[i]);
}
for ( const char & c : s)
res += c;
return res;
}
int main()
{
string s1 = "abcs" ;
string s2 = "cxzca" ;
cout << concatenatedString(s1, s2);
return 0;
}
|
Java
import java.util.HashSet;
public class ConcatenatedString {
public static String concatenatedString(String s1, String s2) {
String res = "" ;
HashSet<Character> s = new HashSet<>();
for ( char c : s2.toCharArray()) {
s.add(c);
}
for ( char c : s1.toCharArray()) {
if (!s.contains(c)) {
res += c;
} else {
s.remove(c);
}
}
for ( char c : s) {
res += c;
}
return res;
}
public static void main(String[] args) {
String s1 = "abcs" ;
String s2 = "cxzca" ;
System.out.println(concatenatedString(s1, s2));
}
}
|
Python3
def concatenatedString(s1: str , s2: str ) - > str :
res = ""
s = set (s2)
for c in s1:
if c not in s:
res + = c
else :
s.remove(c)
res + = "".join(s)
return res
s1 = "abcs"
s2 = "cxzca"
print (concatenatedString(s1, s2))
|
C#
using System;
using System.Collections.Generic;
public class Program
{
public static string ConcatenatedString( string s1, string s2)
{
string res = "" ;
HashSet< char > s = new HashSet< char >(s2);
for ( int i = 0; i < s1.Length; i++) {
if (!s.Contains(s1[i]))
res += s1[i];
else
s.Remove(s1[i]);
}
foreach ( char c in s)
res += c;
return res;
}
public static void Main()
{
string s1 = "abcs" ;
string s2 = "cxzca" ;
Console.WriteLine(ConcatenatedString(s1, s2));
}
}
|
Javascript
function concatenatedString(s1, s2) {
let res = "" ;
let s = new Set(s2);
for (let i = 0; i < s1.length; i++) {
if (!s.has(s1[i]))
res += s1[i];
else
s. delete (s1[i]);
}
for (let c of s)
res += c;
return res;
}
let s1 = "abcs" ;
let s2 = "cxzca" ;
console.log(concatenatedString(s1, s2));
|
Time Complaxity: O(M+N)
Auxiliary Space: O(N)
Method 3: Using Count Arrays
Follow the steps to implement the approach:
- Create two arrays, count1 and count2, of size 26 (assuming lowercase English alphabets) initialized with zeros. These arrays will be used to count the occurrences of each character in s1 and s2, respectively.
- Iterate over each character in s1 and increment the corresponding count in count1.
- Iterate over each character in s2 and increment the corresponding count in count2.
- Create an empty string, modified, to store the modified string.
- Iterate over each character in s1:
- If the count of the character in count2 is 0, it is an uncommon character. Append it to modified.
- Iterate over each character in s2:
- If the count of the character in count1 is 0, it is an uncommon character. Append it to modified.
- If modified is empty, return -1. Otherwise, return modified.
Below is the implementation:
C++
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string concatenatedString(string s1, string s2)
{
vector< int > count1(26, 0);
vector< int > count2(26, 0);
for ( char ch : s1) {
count1[ch - 'a' ]++;
}
for ( char ch : s2) {
count2[ch - 'a' ]++;
}
string modified;
for ( char ch : s1) {
if (count2[ch - 'a' ] == 0) {
modified += ch;
}
}
for ( char ch : s2) {
if (count1[ch - 'a' ] == 0) {
modified += ch;
}
}
if (modified.empty()) {
return "-1" ;
}
return modified;
}
int main()
{
string s1 = "abcs" ;
string s2 = "cxzca" ;
cout << concatenatedString(s1, s2) << endl;
return 0;
}
|
Java
import java.util.Arrays;
public class Main {
public static String concatenatedString(String s1, String s2) {
int [] count1 = new int [ 26 ];
int [] count2 = new int [ 26 ];
for ( char ch : s1.toCharArray()) {
count1[ch - 'a' ]++;
}
for ( char ch : s2.toCharArray()) {
count2[ch - 'a' ]++;
}
StringBuilder modified = new StringBuilder();
for ( char ch : s1.toCharArray()) {
if (count2[ch - 'a' ] == 0 ) {
modified.append(ch);
}
}
for ( char ch : s2.toCharArray()) {
if (count1[ch - 'a' ] == 0 ) {
modified.append(ch);
}
}
if (modified.length() == 0 ) {
return "-1" ;
}
return modified.toString();
}
public static void main(String[] args) {
String s1 = "abcs" ;
String s2 = "cxzca" ;
System.out.println(concatenatedString(s1, s2));
}
}
|
C#
using System;
class GFG {
static string ConcatenatedString( string s1, string s2)
{
int [] count1 = new int [26];
int [] count2 = new int [26];
foreach ( char ch in s1) { count1[ch - 'a' ]++; }
foreach ( char ch in s2) { count2[ch - 'a' ]++; }
string modified
= "" ;
foreach ( char ch in s1)
{
if (count2[ch - 'a' ] == 0) {
modified += ch;
}
}
foreach ( char ch in s2)
{
if (count1[ch - 'a' ] == 0) {
modified += ch;
}
}
if (modified.Length == 0) {
return "-1" ;
}
return modified;
}
static void Main()
{
string s1 = "abcs" ;
string s2 = "cxzca" ;
Console.WriteLine(ConcatenatedString(s1, s2));
Console.ReadLine();
}
}
|
Javascript
function concatenatedString(s1, s2) {
const count1 = new Array(26).fill(0);
const count2 = new Array(26).fill(0);
for (const ch of s1) {
count1[ch.charCodeAt() - 97]++;
}
for (const ch of s2) {
count2[ch.charCodeAt() - 97]++;
}
let modified = '' ;
for (const ch of s1) {
if (count2[ch.charCodeAt() - 97] === 0) {
modified += ch;
}
}
for (const ch of s2) {
if (count1[ch.charCodeAt() - 97] === 0) {
modified += ch;
}
}
if (modified === '' ) {
return '-1' ;
}
return modified;
}
const s1 = 'abcs' ;
const s2 = 'cxzca' ;
console.log(concatenatedString(s1, s2));
|
Time complexity: O(m + n), where m and n are the lengths of s1 and s2, respectively. This is because we iterate over both strings.
Space complexity: O(1). The count1 and count2 arrays have a fixed size of 26, so the space required is constant.
This article is contributed by Harshit Agrawal. 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.