CSES Solutions – Finding Borders
Last Updated :
11 Apr, 2024
A border of a string S is a prefix that is also a suffix of the string but not the whole string. For example, the borders of "abcababcab" are "ab" and "abcab"
Your task is to find all border lengths of a given string.
Examples:
Input: S="abcababcab"
Output: 2 5
Explanation: The string “abcababcab” has two borders: “ab” and “abcab”. “ab” is a prefix of the string (the first two characters) and also a suffix (the last two characters). Its length is 2. “abcab” is also a prefix (the first five characters) and a suffix (the last five characters). Its length is 5.
Input: S="aaabbbbbba"
Output: 1
Explanation: The string “aaabbbbbba” has one border: “a”. “a” is a prefix of the string (the first character) and also a suffix (the last character). Its length is 1.
Approach: To solve the problem, follow the below idea:
We can solve this problem with String comparison using Rolling Hash.
We will compute the hash value of the prefix and suffix strings and if the hash value of both the string is same that means our prefix string and suffix strings are same then print the length of the string.
Prefix and Suffix Hashes: We calculate the prefix hash from left to right and the suffix hash from right to left. We use two different prime numbers p1 and p2 to calculate two different hashes for each prefix and suffix. This reduces the probability of hash collisions.
Hash Comparison: For each position i in the string (from 0 to N-2), we compare the prefix hash and the suffix hash. If they are equal, it means that the prefix and suffix are the same, so we print the length of the border (i+1).
Modular Arithmetic: To avoid overflow and make the hash comparison more efficient, we perform all the calculations under a large prime number MOD.
Precomputation: To make the power calculations more efficient, we precompute the powers of p1 and p2 under MOD.
Step-by-step algorithm:
- Define the prime values p1, p2 and MOD then precompute the power array for hash value calculation.
- Now iterate in the string from [0...N-2] and calculate hash value of prefix and suffix strings.
- if values are same that means our strings are same so we print the length of the string and move to the next iteration.
Below is the implementation of algorithm:
C++
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// Constants
const ll MOD = 1e9 + 7;
const ll p1 = 31;
const ll p2 = 37;
const int maxN = 1e6 + 5;
// Variables
ll pow1[maxN], pow2[maxN], ph1, ph2, sh1, sh2;
// Function to find borders
void solve(string& S, int N)
{
// Initialize the powers of p1 and p2
pow1[0] = pow2[0] = 1;
for (int i = 1; i < N; i++) {
pow1[i] = (pow1[i - 1] * p1) % MOD;
pow2[i] = (pow2[i - 1] * p2) % MOD;
}
// Calculate the prefix and suffix hashes
for (int i = 0; i < N - 1; i++) {
int l = (S[i] - 'a' + 1);
int r = (S[N - i - 1] - 'a' + 1);
ph1 = (ph1 + l * pow1[i]) % MOD;
ph2 = (ph2 + l * pow2[i]) % MOD;
sh1 = (sh1 * p1 + r) % MOD;
sh2 = (sh2 * p2 + r) % MOD;
// If the prefix and suffix hashes are equal, print
// the length of the border
if (ph1 == sh1 && ph2 == sh2)
printf("%d ", i + 1);
}
}
// Drivers code
int main()
{
// Read the input string
string S = "abcababcab";
int N = S.size();
solve(S, N);
return 0;
}
Java
import java.io.*;
import java.util.Arrays;
public class GFG {
// Constants
static final long MOD = 1000000007;
static final long p1 = 31;
static final long p2 = 37;
static final int maxN = 1000005;
// Function to find borders
static void solve(String S, int N) {
// Initialize the powers of p1 and p2
long[] pow1 = new long[N];
long[] pow2 = new long[N];
pow1[0] = pow2[0] = 1;
for (int i = 1; i < N; i++) {
pow1[i] = (pow1[i - 1] * p1) % MOD;
pow2[i] = (pow2[i - 1] * p2) % MOD;
}
// Calculate the prefix and suffix hashes
long ph1 = 0, ph2 = 0, sh1 = 0, sh2 = 0;
for (int i = 0; i < N - 1; i++) {
int l = (S.charAt(i) - 'a' + 1);
int r = (S.charAt(N - i - 1) - 'a' + 1);
ph1 = (ph1 + l * pow1[i]) % MOD;
ph2 = (ph2 + l * pow2[i]) % MOD;
sh1 = (sh1 * p1 + r) % MOD;
sh2 = (sh2 * p2 + r) % MOD;
// If the prefix and suffix hashes are equal, print the length of the border
if (ph1 == sh1 && ph2 == sh2)
System.out.print((i + 1) + " ");
}
}
// Main function
public static void main(String[] args) {
// Read the input string
String S = "abcababcab";
int N = S.length();
solve(S, N);
}
}
//This code is contributed by rohit singh
Python3
# Importing the required libraries
import math
# Constants
MOD = int(1e9) + 7
p1 = 31
p2 = 37
maxN = int(1e6) + 5
# Variables
pow1 = [0]*maxN
pow2 = [0]*maxN
ph1 = ph2 = sh1 = sh2 = 0
# Function to find borders
def solve(S, N):
global pow1, pow2, ph1, ph2, sh1, sh2
# Initialize the powers of p1 and p2
pow1[0] = pow2[0] = 1
for i in range(1, N):
pow1[i] = (pow1[i - 1] * p1) % MOD
pow2[i] = (pow2[i - 1] * p2) % MOD
# Calculate the prefix and suffix hashes
for i in range(N - 1):
l = ord(S[i]) - ord('a') + 1
r = ord(S[N - i - 1]) - ord('a') + 1
ph1 = (ph1 + l * pow1[i]) % MOD
ph2 = (ph2 + l * pow2[i]) % MOD
sh1 = (sh1 * p1 + r) % MOD
sh2 = (sh2 * p2 + r) % MOD
# If the prefix and suffix hashes are equal, print
# the length of the border
if ph1 == sh1 and ph2 == sh2:
print(i + 1, end=" ")
# Driver code
if __name__ == "__main__":
# Read the input string
S = "abcababcab"
N = len(S)
solve(S, N)
JavaScript
// JavaScript code to find borders
// Constants
const MOD = 1000000007;
const p1 = 31;
const p2 = 37;
const maxN = 1000005;
// Function to find borders
function solve(S, N) {
// Initialize the powers of p1 and p2
let pow1 = new Array(N).fill(0);
let pow2 = new Array(N).fill(0);
pow1[0] = pow2[0] = 1;
for (let i = 1; i < N; i++) {
pow1[i] = (pow1[i - 1] * p1) % MOD;
pow2[i] = (pow2[i - 1] * p2) % MOD;
}
// Calculate the prefix and suffix hashes
let ph1 = 0, ph2 = 0, sh1 = 0, sh2 = 0;
for (let i = 0; i < N - 1; i++) {
let l = (S.charCodeAt(i) - 'a'.charCodeAt(0) + 1);
let r = (S.charCodeAt(N - i - 1) - 'a'.charCodeAt(0) + 1);
ph1 = (ph1 + l * pow1[i]) % MOD;
ph2 = (ph2 + l * pow2[i]) % MOD;
sh1 = (sh1 * p1 + r) % MOD;
sh2 = (sh2 * p2 + r) % MOD;
// If the prefix and suffix hashes are equal, print the length of the border
if (ph1 === sh1 && ph2 === sh2)
process.stdout.write((i + 1) + " ");
}
}
// Main function
function main() {
// Input string
let S = "abcababcab";
let N = S.length;
solve(S, N);
}
// Invoke the main function
main();
Time Complexity: O(N), where N is the length of string S.
Auxiliary Space: O(N)
Similar Reads
CSES Solutions - Point in Polygon You are given a polygon of N vertices and a list of M points. Your task is to determine for each point if it is inside, outside or on the boundary of the polygon. The polygon consists of n vertices (x1,y1),(x2,y2),...,(xn,yn). The vertices (xi,yi) and (xi+1,yi+1) are adjacent for i=1,2,...,n-1, and
10 min read
CSES Solutions - Point Location Test There is a line that goes through the points p1 = (x1,y1) and p2 = (x2,y2). There is also a point p3 = (x3,y3). Your task is to determine whether p3 is located on the left or right side of the line or if it touches the line when we are looking from p1 to p2. Example: Input: x1 = 1, y1 = 1, x2 = 5, y
5 min read
Find the coordinate that does not belong to any square Given an array arr[] consisting of (4 * N + 1) pairs of coordinates representing the coordinates of the corners of any N squares such that only one coordinate doesn't belong to any square, the task is to find that coordinate that doesn't belong to any square. Examples: Input: N = 2, arr[] = { {0, 0}
12 min read
Perimeter of the Union of Two Rectangles Given two arrays X[] and Y[], each of length 4, where (X[0], Y[0]) and (X[1], Y[1]) represents the bottom left and top right corners of one rectangle and (X[2], Y[2]) and (X[3], Y[3]) represents the bottom left and top right corners of the other rectangle, the task is to find the perimeter of the ou
7 min read
Find intersection point of lines inside a section Given N lines in two-dimensional space in y = mx + b form and a vertical section. We need to find out whether there is an intersection point inside the given section or not. Examples: In below diagram four lines are there, L1 : y = x + 2 L2 : y = -x + 7 L3 : y = -3 L4 : y = 2x â 7 and vertical secti
9 min read