Given two strings s1 and s2, find whether the two strings contain the same characters that occur in the same order. For example string "Geeks" and string "Geks" contain the same characters in same order.
Examples:
Input: s1 = "Geeks", s2 = "Geks"
Output: true
Explanation: Both strings follow the same character order: G, e, k, s. The first string has one extra repeated e, but the sequence of characters is still the same.
Input: s1 = "Arnab", s2 = "Andrew"
Output: false
Explanation: The character order is not the same in both strings, so the strings do not match.
Table of Content
[Naive Approach] Build Distinct Character Sequences - O(n + m) Time and O(n + m) Space
The idea is to build a new sequence for each string by removing consecutive duplicate characters. After processing both strings, compare the resulting sequences. If they are identical, then both strings contain the same characters in the same order.
#include <iostream>
#include <string>
using namespace std;
bool sameSeq(string &s1, string &s2)
{
string seq1, seq2;
// Build sequence for first string
for (char ch : s1)
{
if (seq1.empty() || seq1.back() != ch)
seq1 += ch;
}
// Build sequence for second string
for (char ch : s2)
{
if (seq2.empty() || seq2.back() != ch)
seq2 += ch;
}
return seq1 == seq2;
}
int main()
{
string s1 = "Geeks";
string s2 = "Geks";
if (sameSeq(s1, s2))
cout << "true";
else
cout << "false";
return 0;
}
public class GFG {
public static boolean sameSeq(String s1, String s2)
{
StringBuilder seq1 = new StringBuilder(),
seq2 = new StringBuilder();
// Build sequence for first string
for (char ch : s1.toCharArray()) {
if (seq1.length() == 0
|| seq1.charAt(seq1.length() - 1) != ch)
seq1.append(ch);
}
// Build sequence for second string
for (char ch : s2.toCharArray()) {
if (seq2.length() == 0
|| seq2.charAt(seq2.length() - 1) != ch)
seq2.append(ch);
}
return seq1.toString().equals(seq2.toString());
}
public static void main(String[] args)
{
String s1 = "Geeks";
String s2 = "Geks";
if (sameSeq(s1, s2))
System.out.println("true");
else
System.out.println("false");
}
}
def sameSeq(s1, s2):
seq1, seq2 = '', ''
# Build sequence for first string
for ch in s1:
if not seq1 or seq1[-1] != ch:
seq1 += ch
# Build sequence for second string
for ch in s2:
if not seq2 or seq2[-1] != ch:
seq2 += ch
return seq1 == seq2
if __name__ == "__main__":
s1 = "Geeks"
s2 = "Geks"
if sameSeq(s1, s2):
print("true")
else:
print("false")
using System;
class GFG {
static bool sameSeq(string s1, string s2)
{
string seq1 = "", seq2 = "";
// Build sequence for first string
foreach(char ch in s1)
{
if (seq1.Length == 0
|| seq1[seq1.Length - 1] != ch)
seq1 += ch;
}
// Build sequence for second string
foreach(char ch in s2)
{
if (seq2.Length == 0
|| seq2[seq2.Length - 1] != ch)
seq2 += ch;
}
return seq1 == seq2;
}
static void Main()
{
string s1 = "Geeks";
string s2 = "Geks";
if (sameSeq(s1, s2))
Console.Write("true");
else
Console.Write("false");
}
}
function sameSeq(s1, s2)
{
let seq1 = "", seq2 = "";
// Build sequence for first string
for (let ch of s1) {
if (seq1.length === 0
|| seq1[seq1.length - 1] !== ch)
seq1 += ch;
}
// Build sequence for second string
for (let ch of s2) {
if (seq2.length === 0
|| seq2[seq2.length - 1] !== ch)
seq2 += ch;
}
return seq1 === seq2;
}
// Driver code
let s1 = "Geeks";
let s2 = "Geks";
if (sameSeq(s1, s2))
console.log("true");
else
console.log("false");
Output
true
[Expected Approach] Two Pointer Traversal - O(n + m) Time and O(1) Space
The idea is to use two pointers to traverse both strings simultaneously. Compare the current characters of both strings and, if they match, skip all their consecutive occurrences. If a mismatch is found, return
false. If both strings are completely traversed together, then they contain the same characters in the same order.
Let us understand with example:
Input: s1 = "Geeks", s2 = "Geks"
- Initialize i = 0 and j = 0. Characters 'G' and 'G' match, so skip their occurrences. Now i = 1, j = 1.
- Characters 'e' and 'e' match. Skip both 'e' characters in s1 and the single 'e' in s2. Now i = 3, j = 2.
- Characters 'k' and 'k' match, so skip them. Now i = 4, j = 3.
- Characters 's' and 's' match, so skip them. Now i = 5, j = 4.
- Both strings are completely traversed, so return true.
#include <iostream>
#include <string>
using namespace std;
bool sameSeq(string &s1, string &s2)
{
int i = 0, j = 0;
int n = s1.size(), m = s2.size();
while (i < n && j < m)
{
// Current character groups must match
if (s1[i] != s2[j])
return false;
char c1 = s1[i];
char c2 = s2[j];
// Skip all consecutive occurrences
while (i < n && s1[i] == c1)
i++;
while (j < m && s2[j] == c2)
j++;
}
// Both strings must be fully processed
return (i == n && j == m);
}
// Driver code
int main()
{
string s1 = "Geeks";
string s2 = "Geks";
if (sameSeq(s1, s2))
cout << "true";
else
cout << "false";
return 0;
}
public class GFG {
public static boolean sameSeq(String s1, String s2)
{
int i = 0, j = 0;
int n = s1.length(), m = s2.length();
while (i < n && j < m) {
// Current character groups must match
if (s1.charAt(i) != s2.charAt(j))
return false;
char c1 = s1.charAt(i);
char c2 = s2.charAt(j);
// Skip all consecutive occurrences
while (i < n && s1.charAt(i) == c1)
i++;
while (j < m && s2.charAt(j) == c2)
j++;
}
// Both strings must be fully processed
return (i == n && j == m);
}
public static void main(String[] args)
{
String s1 = "Geeks";
String s2 = "Geks";
if (sameSeq(s1, s2))
System.out.println("true");
else
System.out.println("false");
}
}
def sameSeq(s1, s2):
i = 0
j = 0
n = len(s1)
m = len(s2)
while i < n and j < m:
# Current character groups must match
if s1[i]!= s2[j]:
return False
c1 = s1[i]
c2 = s2[j]
# Skip all consecutive occurrences
while i < n and s1[i] == c1:
i += 1
while j < m and s2[j] == c2:
j += 1
# Both strings must be fully processed
return i == n and j == m
if __name__ == "__main__":
s1 = "Geeks"
s2 = "Geks"
if sameSeq(s1, s2):
print("true")
else:
print("false")
using System;
public class GFG {
public static bool sameSeq(string s1, string s2)
{
int i = 0, j = 0;
int n = s1.Length, m = s2.Length;
while (i < n && j < m) {
// Current character groups must match
if (s1[i] != s2[j])
return false;
char c1 = s1[i];
char c2 = s2[j];
// Skip all consecutive occurrences
while (i < n && s1[i] == c1)
i++;
while (j < m && s2[j] == c2)
j++;
}
// Both strings must be fully processed
return (i == n && j == m);
}
public static void Main()
{
string s1 = "Geeks";
string s2 = "Geks";
if (sameSeq(s1, s2))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
function sameSeq(s1, s2) {
let i = 0, j = 0;
let n = s1.length, m = s2.length;
while (i < n && j < m) {
// Current character groups must match
if (s1[i]!== s2[j])
return false;
let c1 = s1[i];
let c2 = s2[j];
// Skip all consecutive occurrences
while (i < n && s1[i] === c1)
i++;
while (j < m && s2[j] === c2)
j++;
}
// Both strings must be fully processed
return (i === n && j === m);
}
// Driver code
let s1 = "Geeks";
let s2 = "Geks";
if (sameSeq(s1, s2))
console.log('true');
else
console.log('false');
Output
true