Given a stringĀ sĀ consisting of uppercase English letters, find if it contains the two substringsĀ "XY"Ā andĀ "YX"Ā such that they doĀ notĀ overlap with each other.
The substrings may appear in any order. ReturnĀ trueĀ if such a pair of non-overlapping substrings exists, otherwise returnĀ false.
Examples:
Input: s = "XYYX"
Output: true
Explanation: The string contains the substring "XY" at positions [0, 1] and the substring "YX" at positions [2, 3]. Since these substrings do not overlap, the answer is true.Input: s = "XYX"
Output: false
Explanation: The string contains both "XY" and "YX", but they share the character at index 1. Since the substrings overlap, no valid pair of non-overlapping substrings exists. Therefore, the answer is false.
Table of Content
[Naive Approach] Check All Possible Occurrences - O(n ^ 2) Time and O(n) Space
The idea is to find all occurrences of "XY" and "YX" and check every pair to see whether they overlap or not.
Working of Approach:
- Traverse the string and store the starting indices of "XY" and "YX".
- Compare every "XY" occurrence with every "YX" occurrence.
- Two substrings of length 2 do not overlap if their starting positions differ by at least 2.
- If any such pair is found, return true.
- If no valid pair exists, return false.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
bool overlapPresent(string &s)
{
vector<int> xy, yx;
// Find all occurrences of "XY" and "YX"
for (int i = 0; i + 1 < s.size(); i++)
{
if (s[i] == 'X' && s[i + 1] == 'Y')
xy.push_back(i);
if (s[i] == 'Y' && s[i + 1] == 'X')
yx.push_back(i);
}
// Check every pair of occurrences
for (int i : xy)
{
for (int j : yx)
{
// Check if the two substrings do not overlap
if (abs(i - j) >= 2)
return true;
}
}
return false;
}
int main()
{
string s = "XYYX";
cout << boolalpha << overlapPresent(s);
return 0;
}
import java.util.*;
class GFG {
public boolean overlapPresent(String s)
{
ArrayList<Integer> xy = new ArrayList<>();
ArrayList<Integer> yx = new ArrayList<>();
// Find all occurrences of "XY" and "YX"
for (int i = 0; i + 1 < s.length(); i++) {
if (s.charAt(i) == 'X'
&& s.charAt(i + 1) == 'Y')
xy.add(i);
if (s.charAt(i) == 'Y'
&& s.charAt(i + 1) == 'X')
yx.add(i);
}
// Check every pair of occurrences
for (int i : xy) {
for (int j : yx) {
// Check if the two substrings do not
// overlap
if (Math.abs(i - j) >= 2)
return true;
}
}
return false;
}
public static void main(String[] args)
{
String s = "XYYX";
System.out.println(new GFG().overlapPresent(s));
}
}
def overlapPresent(s):
xy = []
yx = []
# Find all occurrences of "XY" and "YX"
for i in range(len(s) - 1):
if s[i] == 'X' and s[i + 1] == 'Y':
xy.append(i)
if s[i] == 'Y' and s[i + 1] == 'X':
yx.append(i)
# Check every pair of occurrences
for i in xy:
for j in yx:
# Check if the two substrings do not overlap
if abs(i - j) >= 2:
return True
return False
if __name__ == "__main__":
s = "XYYX"
print(overlapPresent(s))
using System;
using System.Collections.Generic;
class GFG {
public bool overlapPresent(string s)
{
List<int> xy = new List<int>();
List<int> yx = new List<int>();
// Find all occurrences of "XY" and "YX"
for (int i = 0; i + 1 < s.Length; i++) {
if (s[i] == 'X' && s[i + 1] == 'Y')
xy.Add(i);
if (s[i] == 'Y' && s[i + 1] == 'X')
yx.Add(i);
}
// Check every pair of occurrences
foreach(int i in xy)
{
foreach(int j in yx)
{
// Check if the two substrings do not
// overlap
if (Math.Abs(i - j) >= 2)
return true;
}
}
return false;
}
public static void Main()
{
string s = "XYYX";
Console.WriteLine(new GFG().overlapPresent(s));
}
}
function overlapPresent(s)
{
let xy = [];
let yx = [];
// Find all occurrences of "XY" and "YX"
for (let i = 0; i + 1 < s.length; i++) {
if (s[i] === "X" && s[i + 1] === "Y")
xy.push(i);
if (s[i] === "Y" && s[i + 1] === "X")
yx.push(i);
}
// Check every pair of occurrences
for (let i of xy) {
for (let j of yx) {
// Check if the two substrings do not overlap
if (Math.abs(i - j) >= 2)
return true;
}
}
return false;
}
// Driver Code
let s = "XYYX";
console.log(overlapPresent(s));
Output
true
[Expected Approach] Using String Search - O(n) Time and O(1) Space
The idea is to find one substring and search for the other starting from two positions ahead, ensuring that the two substrings do not overlap.
Working of Approach:
- Find the first occurrence of "XY" using find().
- If found, search for "YX" starting from posXY + 2.
- Similarly, find "YX" and search for "XY" starting from posYX + 2.
- Starting the second search from pos + 2 ensures that it begins after the first length-2 substring, so the two substrings do not overlap.
- Return true if either order gives a valid pair; otherwise return false.
Let us understand with an example:
Input: s = "XYYX"
- First, find("XY") returns posXY = 0.
- Search for "YX" from index posXY + 2 = 2, which finds "YX" at index 2.
- Since the second substring starts at index 2, it does not overlap with "XY" at indices [0, 1].
- Therefore, the function returns true.
- Output: true
#include <iostream>
#include <string>
using namespace std;
bool overlapPresent(string &s)
{
// Find first occurrence of "XY"
int posXY = s.find("XY");
if (posXY != string::npos)
{
// Search for "YX" starting from index posXY + 2 to avoid overlap
if (s.find("YX", posXY + 2) != string::npos)
return true;
}
// Find first occurrence of "YX"
int posYX = s.find("YX");
// If "YX" exists, check if "XY" exists after non-overlapping position
if (posYX != string::npos)
{
// Search for "XY" starting from index posYX + 2 to avoid overlap
if (s.find("XY", posYX + 2) != string::npos)
return true;
}
return false;
}
int main()
{
string s = "XYYX";
cout << boolalpha << overlapPresent(s);
return 0;
}
class GFG {
public boolean overlapPresent(String s)
{
// Find first occurrence of "XY"
int posXY = s.indexOf("XY");
if (posXY != -1) {
// Search for "YX" starting from index posXY + 2
// to avoid overlap
if (s.indexOf("YX", posXY + 2) != -1)
return true;
}
// Find first occurrence of "YX"
int posYX = s.indexOf("YX");
// If "YX" exists, check if "XY" exists after
// non-overlapping position
if (posYX != -1) {
// Search for "XY" starting from index posYX + 2
// to avoid overlap
if (s.indexOf("XY", posYX + 2) != -1)
return true;
}
return false;
}
public static void main(String[] args)
{
String s = "XYYX";
System.out.println(new GFG().overlapPresent(s));
}
}
def overlapPresent(s):
# Find first occurrence of "XY"
posXY = s.find("XY")
if posXY!= -1:
# Search for "YX" starting from index posXY + 2 to avoid overlap
if s.find("YX", posXY + 2)!= -1:
return True
# Find first occurrence of "YX"
posYX = s.find("YX")
# If "YX" exists, check if "XY" exists after non-overlapping position
if posYX!= -1:
# Search for "XY" starting from index posYX + 2 to avoid overlap
if s.find("XY", posYX + 2)!= -1:
return True
return False
if __name__ == "__main__":
s = "XYYX"
print(overlapPresent(s))
using System;
class GFG {
public bool overlapPresent(string s)
{
// Find first occurrence of "XY"
int posXY = s.IndexOf("XY");
if (posXY != -1) {
// Search for "YX" starting from index posXY + 2
// to avoid overlap
if (s.IndexOf("YX", posXY + 2) != -1)
return true;
}
// Find first occurrence of "YX"
int posYX = s.IndexOf("YX");
// If "YX" exists, check if "XY" exists after
// non-overlapping position
if (posYX != -1) {
// Search for "XY" starting from index posYX + 2
// to avoid overlap
if (s.IndexOf("XY", posYX + 2) != -1)
return true;
}
return false;
}
public static void Main()
{
string s = "XYYX";
Console.WriteLine(new GFG().overlapPresent(s));
}
}
function overlapPresent(s)
{
// Find first occurrence of "XY"
let posXY = s.indexOf("XY");
if (posXY != -1) {
// Search for "YX" starting from index posXY + 2 to
// avoid overlap
if (s.indexOf("YX", posXY + 2) != -1)
return true;
}
// Find first occurrence of "YX"
let posYX = s.indexOf("YX");
// If "YX" exists, check if "XY" exists after
// non-overlapping position
if (posYX != -1) {
// Search for "XY" starting from index posYX + 2 to
// avoid overlap
if (s.indexOf("XY", posYX + 2) != -1)
return true;
}
return false;
}
// Driver Code
let s = "XYYX";
console.log(overlapPresent(s));
Output
true