Maximizing Distance in Binary Strings
Last Updated :
19 Dec, 2023
Given an array of binary strings arr[] of size N (1 <= N <= 103). The task is to find the maximum distance between any pair of these binary strings. The distance between two binary strings is calculated as the sum of their lengths after excluding the common prefix.
Examples:
Input: arr[] = { “01011”, “010110”, “0111”}
Output: 6
Explanation: The strings with the maximum distance between them are “010110” and “0111”, where the common prefix is “01”, Hence, the sum of their lengths after excluding the common prefix: 4 + 2 = 6.
Input: arr[] = {"001", "1", "111111"}
Output: 9
Explanation: The string "001" and "111111" have no common prefix, hence, the sum of their lengths after excluding the common prefix: 3 + 6 = 9.
Maximizing Distance in Binary Strings using Trie:
We need to use of a Trie data structure to efficiently find the maximum distance between binary strings in the given array. We'll store the length of longest suffix from current node till its bottom leaf node. By traversing the Trie, we can find the maximum distance by considering the sum of lengths of non-overlapping substrings of binary strings, resulting in the desired maximum distance calculation. This approach is extremely more efficient than comparing every pair of binary strings directly.
Step-by-step approach:
TrieNode Class:
- Create a TrieNode class with attributes val for storing the length of string after excluding the common prefix, an ending flag, and left and right child pointers.
Build Trie:
- Create a buildTree() function to build a Trie from an array of binary strings (nums).
- Initialize a pointer cur to the root node and iterate through each binary string in given array arr[].
- For each character in the binary string:
- If it's '0', traverse to the left child (0) in the Trie. If the left child doesn't exist, create it and update its val.
- If it's '1', traverse to the right child (1) in the Trie. If the right child doesn't exist, create it and update its val.
- Mark the current node as an ending node (isEnding = true)
Calculate Maximum Distance:
- Create a maxDistance() function to calculate the maximum distance between binary strings using the constructed Trie.
- Create the Trie root node and build the Trie structure using buildTree() by above mentioned steps.
- Initialize max_distance = 0 and a queue (q) for breadth-first traversal.
- Start with the root node and push it into the queue.
- While the queue is not empty:
- Dequeue the front node cur.
- If cur has left or right children:
- If it has both left and right children, calculate the maximum distance as the sum of their val and update max_distance.
- If cur is an ending node, calculate the maximum distance considering either the left or right child with val and update max_distance.
- Enqueue the left and right children of cur, if they exist.
- Return the max_distance.
Below is the implementation of the above approach:
C++
// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
// Define a class for a TrieNode
class TrieNode {
public:
// Store the length of longest suffix from
// current node till its bottom leaf node
int val;
// Indicates if this node is the end of a
// number
bool isEnding;
// Pointer to the left child (0)
TrieNode* left;
// Pointer to the right child (1)
TrieNode* right;
TrieNode(int val)
: val(val)
, isEnding(false)
, left(nullptr)
, right(nullptr)
{
}
};
// Function to build the Trie tree
void buildTree(TrieNode* root, vector<string>& nums)
{
for (int i = 0; i < nums.size(); i++) {
TrieNode* cur = root;
int j = 0, len = nums[i].length();
while (j < len) {
if (nums[i][j] == '0') {
if (cur->left == nullptr) {
cur->left = new TrieNode(len - j);
}
else {
cur->left->val
= max(cur->left->val, len - j);
}
cur = cur->left;
}
else {
if (cur->right == nullptr) {
cur->right = new TrieNode(len - j);
}
else {
cur->right->val
= max(cur->right->val, len - j);
}
cur = cur->right;
}
j++;
}
cur->isEnding = true;
}
return;
}
// Function to find the maximum distance in the Trie
int maxDistance(vector<string>& nums)
{
TrieNode* root = new TrieNode(0);
buildTree(root, nums);
int max_distance = 0;
queue<TrieNode*> q;
q.push(root);
while (!q.empty()) {
TrieNode* cur = q.front();
q.pop();
if (cur->left || cur->right) {
if (cur->left && cur->right) {
// Calculate the maximum distance for
// common prefixes with both left
// and right branches
max_distance
= max(max_distance,
cur->left->val + cur->right->val);
}
else if (cur->isEnding) {
// Calculate the maximum distance for
// common prefixes with either
// left or right branch
max_distance
= max(max_distance,
cur->left ? cur->left->val
: cur->right->val);
}
}
if (cur->left)
q.push(cur->left);
if (cur->right)
q.push(cur->right);
}
return max_distance;
}
// Drivers code
int main()
{
vector<string> nums = { "01011", "010110", "0111" };
int max_distance = maxDistance(nums);
// Function Call
cout << max_distance;
return 0;
}
Java
// Java code for the above approach:
import java.util.LinkedList;
import java.util.Queue;
// Define a class for a TrieNode
class TrieNode {
// Store the length of longest suffix from
// current node till its bottom leaf node
int val;
// Indicates if this node is the end of a
// number
boolean isEnding;
// Pointer to the left child (0)
TrieNode left;
// Pointer to the right child (1)
TrieNode right;
TrieNode(int val)
{
this.val = val;
isEnding = false;
left = right = null;
}
}
class GFG {
// Function to build the Trie tree
static void buildTree(TrieNode root, String[] nums)
{
for (int i = 0; i < nums.length; i++) {
TrieNode cur = root;
int j = 0, len = nums[i].length();
while (j < len) {
if (nums[i].charAt(j) == '0') {
if (cur.left == null) {
cur.left = new TrieNode(len - j);
}
else {
cur.left.val = Math.max(
cur.left.val, len - j);
}
cur = cur.left;
}
else {
if (cur.right == null) {
cur.right = new TrieNode(len - j);
}
else {
cur.right.val = Math.max(
cur.right.val, len - j);
}
cur = cur.right;
}
j++;
}
cur.isEnding = true;
}
}
// Function to find the maximum distance in the Trie
static int maxDistance(String[] nums)
{
TrieNode root = new TrieNode(0);
buildTree(root, nums);
int max_distance = 0;
Queue<TrieNode> q = new LinkedList<>();
q.add(root);
while (!q.isEmpty()) {
TrieNode cur = q.poll();
if (cur.left != null || cur.right != null) {
if (cur.left != null && cur.right != null) {
// Calculate the maximum distance for
// common prefixes with both left
// and right branches
max_distance = Math.max(
max_distance,
cur.left.val + cur.right.val);
}
else if (cur.isEnding) {
// Calculate the maximum distance for
// common prefixes with either
// left or right branch
max_distance = Math.max(
max_distance, cur.left != null
? cur.left.val
: cur.right.val);
}
}
if (cur.left != null)
q.add(cur.left);
if (cur.right != null)
q.add(cur.right);
}
return max_distance;
}
// Drivers code
public static void main(String[] args)
{
String[] nums = { "01011", "010110", "0111" };
int max_distance = maxDistance(nums);
// Function Call
System.out.println(max_distance);
}
}
// This code is contributed by ragul21
Python3
# Python Implementation;
class TrieNode:
def __init__(self, val):
self.val = val
self.isEnding = False
self.left = None
self.right = None
def buildTree(root, nums):
for num in nums:
cur = root
j = 0
length = len(num)
while j < length:
if num[j] == '0':
if cur.left is None:
cur.left = TrieNode(length - j)
else:
cur.left.val = max(cur.left.val, length - j)
cur = cur.left
else:
if cur.right is None:
cur.right = TrieNode(length - j)
else:
cur.right.val = max(cur.right.val, length - j)
cur = cur.right
j += 1
cur.isEnding = True
def maxDistance(nums):
root = TrieNode(0)
buildTree(root, nums)
max_distance = 0
queue = []
queue.append(root)
while queue:
cur = queue.pop(0)
if cur.left or cur.right:
if cur.left and cur.right:
max_distance = max(max_distance, cur.left.val + cur.right.val)
elif cur.isEnding:
max_distance = max(
max_distance, cur.left.val if cur.left else cur.right.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return max_distance
nums = ["01011", "010110", "0111"]
max_distance = maxDistance(nums)
print(max_distance)
# This code is contributed by Tapesh(tapeshdua420)
C#
using System;
using System.Collections.Generic;
// Define a class for a TrieNode
class TrieNode
{
// Store the length of the longest suffix from
// the current node till its bottom leaf node
public int Val { get; set; }
// Indicates if this node is the end of a number
public bool IsEnding { get; set; }
// Pointer to the left child (0)
public TrieNode Left { get; set; }
// Pointer to the right child (1)
public TrieNode Right { get; set; }
public TrieNode(int val)
{
Val = val;
IsEnding = false;
Left = null;
Right = null;
}
}
class Program
{
// Function to build the Trie tree
static void BuildTree(TrieNode root, List<string> nums)
{
foreach (var num in nums)
{
TrieNode cur = root;
int j = 0, len = num.Length;
while (j < len)
{
if (num[j] == '0')
{
if (cur.Left == null)
{
cur.Left = new TrieNode(len - j);
}
else
{
cur.Left.Val = Math.Max(cur.Left.Val, len - j);
}
cur = cur.Left;
}
else
{
if (cur.Right == null)
{
cur.Right = new TrieNode(len - j);
}
else
{
cur.Right.Val = Math.Max(cur.Right.Val, len - j);
}
cur = cur.Right;
}
j++;
}
cur.IsEnding = true;
}
}
// Function to find the maximum distance in the Trie
static int MaxDistance(List<string> nums)
{
TrieNode root = new TrieNode(0);
BuildTree(root, nums);
int maxDistance = 0;
Queue<TrieNode> queue = new Queue<TrieNode>();
queue.Enqueue(root);
while (queue.Count > 0)
{
TrieNode cur = queue.Dequeue();
if (cur.Left != null || cur.Right != null)
{
if (cur.Left != null && cur.Right != null)
{
// Calculate the maximum distance for common prefixes with both left and right branches
maxDistance = Math.Max(maxDistance, cur.Left.Val + cur.Right.Val);
}
else if (cur.IsEnding)
{
// Calculate the maximum distance for common prefixes with either left or right branch
maxDistance = Math.Max(maxDistance, cur.Left != null ? cur.Left.Val : cur.Right.Val);
}
}
if (cur.Left != null)
queue.Enqueue(cur.Left);
if (cur.Right != null)
queue.Enqueue(cur.Right);
}
return maxDistance;
}
// Drivers code
static void Main()
{
List<string> nums = new List<string> { "01011", "010110", "0111" };
int maxDistance = MaxDistance(nums);
// Display the result
Console.WriteLine(maxDistance);
}
}
JavaScript
class TrieNode {
constructor(val) {
this.val = val;
this.isEnding = false;
this.left = null;
this.right = null;
}
}
// Function to build the Trie tree
function buildTree(root, nums) {
for (let i = 0; i < nums.length; i++) {
let cur = root;
let j = 0, len = nums[i].length;
while (j < len) {
if (nums[i][j] === '0') {
if (!cur.left) {
cur.left = new TrieNode(len - j);
} else {
cur.left.val = Math.max(cur.left.val, len - j);
}
cur = cur.left;
} else {
if (!cur.right) {
cur.right = new TrieNode(len - j);
} else {
cur.right.val = Math.max(cur.right.val, len - j);
}
cur = cur.right;
}
j++;
}
cur.isEnding = true;
}
}
// Function to find the maximum distance in the Trie
function maxDistance(nums) {
const root = new TrieNode(0);
buildTree(root, nums);
let max_distance = 0;
const queue = [root];
while (queue.length > 0) {
const cur = queue.shift();
if (cur.left || cur.right) {
if (cur.left && cur.right) {
// Calculate the maximum distance for
// common prefixes with both left
// and right branches
max_distance =
Math.max(max_distance, cur.left.val + cur.right.val);
} else if (cur.isEnding) {
// Calculate the maximum distance for
// common prefixes with either
// left or right branch
max_distance =
Math.max(max_distance, cur.left ? cur.left.val : cur.right.val);
}
}
if (cur.left) queue.push(cur.left);
if (cur.right) queue.push(cur.right);
}
return max_distance;
}
// Driver code
const nums = ["01011", "010110", "0111"];
const max_distance = maxDistance(nums);
// Function Call
console.log(max_distance);
Time Complexity: O(N * M), where N is the number of binary strings and M is the average length of the binary strings.
Auxiliary Space: O(N * M)
Similar Reads
Hamming Distance between two strings
You are given two strings of equal length, you have to find the Hamming Distance between these string. Where the Hamming distance between two strings of equal length is the number of positions at which the corresponding character is different. Examples: Input : str1[] = "geeksforgeeks", str2[] = "ge
4 min read
Maximum difference of zeros and ones in binary string
Given a binary string of 0s and 1s. The task is to find the length of the substring which is having a maximum difference between the number of 0s and the number of 1s (number of 0s - number of 1s). In case of all 1s print -1. Examples: Input : S = "11000010001"Output : 6From index 2 to index 9, ther
15 min read
Binary String Partitioning
Given a Binary String S consisting of N bits, integers K and D. The task is to determine whether the maximum absolute difference among all K disjoint strings in S can be made less than D. Note: Some of the K strings can be empty, and each character of S can only belong to one of the K strings Exampl
5 min read
Maximum distance between adjacent 1s in given Binary String
Given a binary string S containing N characters, the task is to find the maximum distance between two adjacent 1's. Examples: Input: S = "1010010"Output: 3Explanation: There are 2 sets of adjacent 1's in the given index on the indices {0, 2} and {2, 5}. The one with the maximum distance among them i
12 min read
Maximize ascii sum removing K characters in String
Given a string s and an integer K, the task is to remove K characters from the string such that the sum of ASCII (American Standard Code for Information Interchange) values of the remaining characters is maximized. Examples: Input: s = "word", K = 2Output: 233Explanation: We need to remove exactly 2
9 min read
Maximum distance between two 1's in Binary representation of N
Given a number N, the task is to find the maximum distance between two 1's in the binary representation of given N. Print -1 if binary representation contains less than two 1's.Examples: Input: N = 131 Output: 7 131 in binary = 10000011. The maximum distance between two 1's = 7. Input: N = 8 Output:
5 min read
Maximize sum by splitting given binary strings based on given conditions
Given two binary strings str1 and str2 each of length N, the task is to split the strings in such a way that the sum is maximum with given conditions. Split both strings at the same position into equal length substrings.If both the substrings have only 0's then the value of that substring to be adde
7 min read
Maximum Consecutive Zeroes in Concatenated Binary String
You are given a binary string str of length n. Suppose you create another string of size n * k by concatenating k copies of str together. What is the maximum size of a substring of the concatenated string consisting only of 0's? Given that k > 1. Examples: Input : str = "110010", k = 2 Output : 2
8 min read
Find maximum distance between any city and station
Given the number of cities n numbered from 0 to n-1 and the cities in which stations are located, the task is to find the maximum distance between any city and its nearest station. Note that the cities with stations can be given in any order. Examples: Input: numOfCities = 6, stations = [1, 4] Outpu
7 min read
Minimum distance between duplicates in a String
Given a string S and its length N (provided N > 0). The task is to find the minimum distance between same repeating characters, if no repeating characters present in string S return -1. Examples: Input: S = "geeksforgeeks", N = 13Output: 0 Explanation: The repeating characters in string S = "geek
15+ min read