Count substrings with same first and last characters
We are given a string S, we need to find count of all contiguous substrings starting and ending with same character.
Examples :
Input : S = "abcab"
Output : 7
There are 15 substrings of "abcab"
a, ab, abc, abca, abcab, b, bc, bca
bcab, c, ca, cab, a, ab, b
Out of the above substrings, there
are 7 substrings : a, abca, b, bcab,
c, a and b.
Input : S = "aba"
Output : 4
The substrings are a, b, a and aba
Method 1 (Simple): In this approach, we use brute force and find all the sub-strings and pass them through our function checkEquality to see if starting and ending characters are same.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int checkEquality(string s)
{
return (s[0] == s[s.size() - 1]);
}
int countSubstringWithEqualEnds(string s)
{
int result = 0;
int n = s.length();
for ( int i = 0; i < n; i++)
for ( int len = 1; len <= n-i; len++)
if (checkEquality(s.substr(i, len)))
result++;
return result;
}
int main()
{
string s( "abcab" );
cout << countSubstringWithEqualEnds(s);
return 0;
}
|
Java
public class GFG {
static boolean checkEquality(String s)
{
return (s.charAt( 0 ) == s.charAt(s.length() - 1 ));
}
static int countSubstringWithEqualEnds(String s)
{
int result = 0 ;
int n = s.length();
for ( int i = 0 ; i < n; i++)
for ( int len = 1 ; len <= n-i; len++)
if (checkEquality(s.substring(i, i + len)))
result++;
return result;
}
public static void main(String args[])
{
String s = "abcab" ;
System.out.println(countSubstringWithEqualEnds(s));
}
}
|
Python3
def checkEquality(s):
return ( ord (s[ 0 ]) = = ord (s[ len (s) - 1 ]));
def countSubstringWithEqualEnds(s):
result = 0 ;
n = len (s);
for i in range (n):
for j in range ( 1 ,n - i + 1 ):
if (checkEquality(s[i:i + j])):
result + = 1 ;
return result;
s = "abcab" ;
print (countSubstringWithEqualEnds(s));
|
C#
using System;
class GFG
{
static bool checkEquality( string s)
{
return (s[0] == s[s.Length - 1]);
}
static int countSubstringWithEqualEnds( string s)
{
int result = 0;
int n = s.Length;
for ( int i = 0; i < n; i++)
for ( int len = 1; len <= n-i; len++)
if (checkEquality(s.Substring(i, len)))
result++;
return result;
}
public static void Main()
{
string s = "abcab" ;
Console.WriteLine(countSubstringWithEqualEnds(s));
}
}
|
PHP
<?php
function checkEquality( $s )
{
return ( $s [0] == $s [ strlen ( $s ) - 1]);
}
function countSubstringWithEqualEnds( $s )
{
$result = 0;
$n = strlen ( $s );
for ( $i = 0; $i < $n ; $i ++)
for ( $len = 1; $len <= $n - $i ; $len ++)
if (checkEquality( substr ( $s , $i , $len )))
$result ++;
return $result ;
}
$s = "abcab" ;
print (countSubstringWithEqualEnds( $s ));
?>
|
Javascript
<script>
function checkEquality(s)
{
return (s.charAt(0) == s.charAt(s.length - 1));
}
function countSubstringWithEqualEnds(s)
{
var result = 0;
var n = s.length;
for ( var i = 0; i < n; i++)
for ( var len = 1; len <= n-i; len++)
if (checkEquality(s.substring(i, i + len)))
result++;
return result;
}
var s = "abcab" ;
document.write(countSubstringWithEqualEnds(s));
</script>
|
Although the above code works fine, it’s not efficient as its time complexity is O(n2). Note that there are n*(n+1)/2 substrings of a string of length n. This solution also requires O(n) extra space as we one by one create all substrings.
Method 2 (Space Efficient): In this approach we don’t actually generate substrings rather we traverse the string in such a manner so that we can easily compare first and last characters.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int countSubstringWithEqualEnds(string s)
{
int result = 0;
int n = s.length();
for ( int i=0; i<n; i++)
for ( int j=i; j<n; j++)
if (s[i] == s[j])
result++;
return result;
}
int main()
{
string s( "abcab" );
cout << countSubstringWithEqualEnds(s);
return 0;
}
|
Java
public class GFG {
static int countSubstringWithEqualEnds(String s)
{
int result = 0 ;
int n = s.length();
for ( int i = 0 ; i < n; i++)
for ( int j = i; j < n; j++)
if (s.charAt(i) == s.charAt(j))
result++;
return result;
}
public static void main(String args[])
{
String s = "abcab" ;
System.out.println(countSubstringWithEqualEnds(s));
}
}
|
Python3
def countSubstringWithEqualEnds(s):
result = 0 ;
n = len (s);
for i in range (n):
for j in range (i, n):
if (s[i] = = s[j]):
result = result + 1
return result
s = "abcab" ;
print (countSubstringWithEqualEnds(s))
|
C#
using System;
public class GFG {
static int countSubstringWithEqualEnds( string s)
{
int result = 0;
int n = s.Length;
for ( int i = 0; i < n; i++)
for ( int j = i; j < n; j++)
if (s[i] == s[j])
result++;
return result;
}
public static void Main()
{
string s = "abcab" ;
Console.Write(countSubstringWithEqualEnds(s));
}
}
|
PHP
<?php
function countSubstringWithEqualEnds( $s )
{
$result = 0;
$n = strlen ( $s );
for ( $i = 0; $i < $n ; $i ++)
for ( $j = $i ; $j < $n ; $j ++)
if ( $s [ $i ] == $s [ $j ])
$result ++;
return $result ;
}
$s = "abcab" ;
echo countSubstringWithEqualEnds( $s );
|
Javascript
<script>
function countSubstringWithEqualEnds(s)
{
var result = 0;
var n = s.length;
for (i = 0; i < n; i++)
for (j = i; j < n; j++)
if (s.charAt(i) == s.charAt(j))
result++;
return result;
}
var s = "abcab" ;
document.write(countSubstringWithEqualEnds(s));
</script>
|
In the above code although we have reduced the extra space to O(1) time complexity is still O(n^2).
Method 3 (Best approach) : Now if we carefully observe then we can realize that the answer just depends on frequencies of characters in the original string. For example in string abcab, frequency of ‘a’ is 2, and substrings contributing to answering are a, abca and a respectively, a total of 3, which is calculated by (frequency of ‘a’+1)C2.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 26;
int countSubstringWithEqualEnds(string s)
{
int result = 0;
int n = s.length();
int count[MAX_CHAR] = {0};
for ( int i=0; i<n; i++)
count[s[i]- 'a' ]++;
for ( int i=0; i<MAX_CHAR; i++)
result += (count[i]*(count[i]+1)/2);
return result;
}
int main()
{
string s( "abcab" );
cout << countSubstringWithEqualEnds(s);
return 0;
}
|
Java
public class GFG {
static final int MAX_CHAR = 26 ;
static int countSubstringWithEqualEnds(String s)
{
int result = 0 ;
int n = s.length();
int [] count = new int [MAX_CHAR];
for ( int i = 0 ; i < n; i++)
count[s.charAt(i)- 'a' ]++;
for ( int i = 0 ; i < MAX_CHAR; i++)
result += (count[i] * (count[i] + 1 ) / 2 );
return result;
}
public static void main(String args[])
{
String s = "abcab" ;
System.out.println(countSubstringWithEqualEnds(s));
}
}
|
Python3
MAX_CHAR = 26 ;
def countSubstringWithEqualEnds(s):
result = 0 ;
n = len (s);
count = [ 0 ] * MAX_CHAR;
for i in range (n):
count[ ord (s[i]) - ord ( 'a' )] + = 1 ;
for i in range (MAX_CHAR):
result + = (count[i] * (count[i] + 1 ) / 2 );
return result;
s = "abcab" ;
print (countSubstringWithEqualEnds(s));
|
C#
using System;
class GFG {
static readonly int MAX_CHAR = 26;
static int countSubstringWithEqualEnds(String s)
{
int result = 0;
int n = s.Length;
int [] count = new int [MAX_CHAR];
for ( int i = 0; i < n; i++)
count[s[i] - 'a' ]++;
for ( int i = 0; i < MAX_CHAR; i++)
result += (count[i] * (count[i] + 1) / 2);
return result;
}
public static void Main()
{
String s = "abcab" ;
Console.Write(countSubstringWithEqualEnds(s));
}
}
|
PHP
<?php
$MAX_CHAR = 26;
function countSubstringWithEqualEnds( $s )
{
global $MAX_CHAR ;
$result = 0;
$n = strlen ( $s );
$count = array_fill (0, $MAX_CHAR , 0);
for ( $i = 0; $i < $n ; $i ++)
$count [ord( $s [ $i ]) - ord( 'a' )]++;
for ( $i = 0; $i < $MAX_CHAR ; $i ++)
$result += ( $count [ $i ] *
( $count [ $i ] + 1) / 2);
return $result ;
}
$s = "abcab" ;
echo countSubstringWithEqualEnds( $s );
?>
|
Javascript
<script>
var MAX_CHAR = 26;
function countSubstringWithEqualEnds(s)
{
var result = 0;
var n = s.length;
var count = Array.from({length: MAX_CHAR}, (_, i) => 0);
for ( var i = 0; i < n; i++)
count[s.charAt(i).charCodeAt(0)- 'a' .charCodeAt(0)]++;
for ( var i = 0; i < MAX_CHAR; i++)
result += (count[i] * (count[i] + 1) / 2);
return result;
}
var s = "abcab" ;
document.write(countSubstringWithEqualEnds(s));
</script>
|
The above code has time complexity of O(n) and requires O(1) extra space.
Recursive solution to count substrings with same first and last characters
Last Updated :
08 Jul, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...