Given two binary strings s and t. The task is to rearrange the string s in such a way that the occurrence of string t as a sub-string in s is maximum.
Examples:
Input: s = “101101”, t = “110”
Output: 110110Input: s = “10”, t = “11100”
Output: 10Input: s = “11000100”, t = “101”
Output: 10101000
Approach: If we can not make any occurrence of string t in string s then output any permutation of s. Otherwise, start the rearranged string with t. Now we will make the next occurrence of string t in string s as left as possible in order maximize the count of occurrence. To achieve this we will find the largest suffix of string t that matches the prefix of string t
of the same length. It can be found by Prefix Function, Z-Function or Hashes.
Below is the implementation of the above approach:
# Python3 implementation of the approach from collections import defaultdict
# Function to return the length of maximum # proper suffix which is also proper prefix def Prefix_Array(t):
m = len (t)
arr = [ - 1 ] * m
k = - 1
for i in range ( 1 , m):
while k> - 1 and t[k + 1 ]! = t[i]:
k = arr[k]
if t[k + 1 ] = = t[i]:
k + = 1
arr[i] = k
return arr[ - 1 ]
# Function to return the rearranged string def Rearranged(ds, dt):
check = Prefix_Array(t)
# If there is no proper suffix which is
# also a proper prefix
if check = = - 1 :
if ds[ '1' ]<dt[ '1' ] or ds[ '0' ]<dt[ '0' ]:
return s
# If count of 1's in string t is 0
if dt[ '1' ] = = 0 and ds[ '0' ]! = 0 :
n = ds[ '0' ] / / dt[ '0' ]
temp = t * n
ds[ '0' ] - = n * dt[ '0' ]
while ds[ '1' ]> 0 :
temp + = '1'
ds[ '1' ] - = 1
while ds[ '0' ]> 0 :
temp + = '0'
ds[ '0' ] - = 1
# Return the rearranged string
return temp
# If count of 0's in string t is 0
if dt[ '0' ] = = 0 and ds[ '1' ]! = 0 :
n = ds[ '1' ] / / dt[ '1' ]
temp = t * n
ds[ '1' ] - = n * dt[ '1' ]
while ds[ '1' ]> 0 :
temp + = '1'
ds[ '1' ] - = 1
while ds[ '0' ]> 0 :
temp + = '0'
ds[ '0' ] - = 1
# Return the rearranged string
return temp
# If both 1's and 0's are present in
# string t
m1 = ds[ '1' ] / / dt[ '1' ]
m2 = ds[ '0' ] / / dt[ '0' ]
n = min (m1, m2)
temp = t * n
ds[ '1' ] - = n * dt[ '1' ]
ds[ '0' ] - = n * dt[ '0' ]
while ds[ '1' ]> 0 :
temp + = '1'
ds[ '1' ] - = 1
while ds[ '0' ]> 0 :
temp + = '0'
ds[ '0' ] - = 1
return temp
# If there is a suffix which is
# also a prefix in string t
else :
if ds[ '1' ]<dt[ '1' ] or ds[ '0' ]<dt[ '0' ]:
return s
# Append the remaining string each time
r = t[check + 1 :]
dr = defaultdict( int )
for v in r:
dr[v] + = 1
temp = t
ds[ '1' ] - = dt[ '1' ]
ds[ '0' ] - = dt[ '0' ]
# If we can't form the string t
# by the remaining 0's and 1's
if ds[ '1' ]<dr[ '1' ] or ds[ '0' ]<dr[ '0' ]:
while ds[ '1' ]> 0 :
temp + = '1'
ds[ '1' ] - = 1
while ds[ '0' ]> 0 :
temp + = '0'
ds[ '0' ] - = 1
return temp
# If count of 1's in string r is 0
if dr[ '1' ] = = 0 and ds[ '0' ]! = 0 :
n = ds[ '0' ] / / dr[ '0' ]
temp + = r * n
ds[ '0' ] - = n * dr[ '0' ]
while ds[ '1' ]> 0 :
temp + = '1'
ds[ '1' ] - = 1
while ds[ '0' ]> 0 :
temp + = '0'
ds[ '0' ] - = 1
return temp
# If count of 0's in string r is 0
if dr[ '0' ] = = 0 and ds[ '1' ]! = 0 :
n = ds[ '1' ] / / dr[ '1' ]
temp + = r * n
ds[ '1' ] - = n * dr[ '1' ]
while ds[ '1' ]> 0 :
temp + = '1'
ds[ '1' ] - = 1
while ds[ '0' ]> 0 :
temp + = '0'
ds[ '0' ] - = 1
return temp
# If string r have both 0's and 1's
m1 = ds[ '1' ] / / dr[ '1' ]
m2 = ds[ '0' ] / / dr[ '0' ]
n = min (m1, m2)
temp + = r * n
ds[ '1' ] - = n * dr[ '1' ]
ds[ '0' ] - = n * dr[ '0' ]
while ds[ '1' ]> 0 :
temp + = '1'
ds[ '1' ] - = 1
while ds[ '0' ]> 0 :
temp + = '0'
ds[ '0' ] - = 1
return temp
# Driver code if __name__ = = "__main__" :
s = "10101000"
t = "101"
# Count of 0's and 1's in string s
ds = defaultdict( int )
# Count of 0's and 1's in string t
dt = defaultdict( int )
for i in s:
ds[i] = ds[i] + 1
for i in t:
dt[i] = dt[i] + 1
print (Rearranged(ds, dt))
|
10101000