Existence of a Substring in a String and Its Reverse
EasyUpdated: Aug 2, 2025
Practice on:
Problem
Given a**** string s, find any substring of length 2 which is also present in the reverse of s.
Return true if such a substring exists, andfalse otherwise.
Examples
Example 1
Input: s = "leetcode"
Output: true
Explanation: Substring `"ee"` is of length `2` which is also present in
`reverse(s) == "edocteel"`.
Example 2
Input: s = "abcba"
Output: true
Explanation: All of the substrings of length `2` `"ab"`, `"bc"`, `"cb"`,
`"ba"` are also present in `reverse(s) == "abcba"`.
Example 3
Input: s = "abcd"
Output: false
Explanation: There is no substring of length `2` in `s`, which is also
present in the reverse of `s`.
Constraints
1 <= s.length <= 100sconsists only of lowercase English letters.
Solution
Method 1 – Hash Set for Substrings
Intuition
If any substring of length 2 in s is also present in the reverse of s, then there is an overlap. We can collect all substrings of length 2 from s and from reverse(s), and check for intersection.
Approach
- If the length of
sis less than 2, returnfalse. - Collect all substrings of length 2 from
sinto a set. - Reverse
sand collect all substrings of length 2 from the reversed string into another set. - Check if there is any intersection between the two sets.
- Return
trueif there is an intersection, otherwisefalse.
Code
C++
class Solution {
public:
bool hasSubstringInReverse(string s) {
if (s.size() < 2) return false;
unordered_set<string> subs, revsubs;
for (int i = 0; i + 1 < s.size(); ++i) subs.insert(s.substr(i, 2));
reverse(s.begin(), s.end());
for (int i = 0; i + 1 < s.size(); ++i) revsubs.insert(s.substr(i, 2));
for (auto& sub : subs) if (revsubs.count(sub)) return true;
return false;
}
};
Java
class Solution {
public boolean hasSubstringInReverse(String s) {
if (s.length() < 2) return false;
Set<String> subs = new HashSet<>();
Set<String> revsubs = new HashSet<>();
for (int i = 0; i + 1 < s.length(); ++i) subs.add(s.substring(i, i+2));
StringBuilder sb = new StringBuilder(s).reverse();
for (int i = 0; i + 1 < s.length(); ++i) revsubs.add(sb.substring(i, i+2));
for (String sub : subs) if (revsubs.contains(sub)) return true;
return false;
}
}
Python
class Solution:
def hasSubstringInReverse(self, s: str) -> bool:
if len(s) < 2:
return False
subs = set(s[i:i+2] for i in range(len(s)-1))
rev = s[::-1]
revsubs = set(rev[i:i+2] for i in range(len(rev)-1))
return not subs.isdisjoint(revsubs)
Rust
use std::collections::HashSet;
impl Solution {
pub fn has_substring_in_reverse(s: String) -> bool {
if s.len() < 2 { return false; }
let subs: HashSet<_> = s.as_bytes().windows(2).map(|w| w.to_vec()).collect();
let rev: Vec<u8> = s.bytes().rev().collect();
let revsubs: HashSet<_> = rev.windows(2).map(|w| w.to_vec()).collect();
subs.intersection(&revsubs).next().is_some()
}
}
TypeScript
class Solution {
hasSubstringInReverse(s: string): boolean {
if (s.length < 2) return false;
const subs = new Set<string>();
for (let i = 0; i + 1 < s.length; ++i) subs.add(s.substring(i, i+2));
const rev = s.split('').reverse().join('');
const revsubs = new Set<string>();
for (let i = 0; i + 1 < rev.length; ++i) revsubs.add(rev.substring(i, i+2));
for (const sub of subs) if (revsubs.has(sub)) return true;
return false;
}
}
Complexity
- ⏰ Time complexity:
O(n), wherenis the length ofs(since substring extraction and set operations are linear). - 🧺 Space complexity:
O(n), for storing the sets of substrings.