Given two strings source and target of equal length, and two positive integers, maxCost, and conversionCost, the task is to find the indices of the longest substring in source that can be converted into the same substring in target with a cost less than or equal to maxCost, where each character conversion having a cost of conversionCost units.
Note: If multiple valid substrings exist, return any one of them.
Examples:
Input: source = “abcd”, target = “bcdf”, conversionCost = 1, maxCost = 3 Output: 0 2 Explanation: The substring of source from index 0 to 2 is “abc” which can change to “bcd” in target. The cost of changing would be 3 <= maxCost. And the maximum length possible is 3.
Input: source = “adcf”, target = “cdef”, conversionCost = 3, maxCost = 5 Output: 1 3
Finding Longest Substring Conversion using Binary Search:
The idea is to use binary search on answer to find the maximum possible length, and for each length, check its possible to change within maxCost and based on that update the search space of answer and keep track of indices of start and end position of valid substring.
Step-by-step approach:
- Initialize low to 1 and high to the string’s length.
- Initialize result to store the maximum length of a valid substring.
- While low is less than high, do the following:
- Calculate mid = (start + end) / 2
- Check if mid is a possible length for a valid substring.
- If valid, update result to mid and shift low to mid + 1.
- Otherwise, shift high to mid.
- If a valid substring is found, print its starting and ending indices.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int startPos = -1, endPos = -1;
bool isValid( int len, string& s, string& t,
int conversionCost, int maxCost)
{
int start = 0, end = 0, n = s.size();
int currCost = 0;
while (end < n) {
if (s[end] != t[end]) {
currCost += conversionCost;
}
if (end - start + 1 == len) {
if (currCost <= maxCost) {
startPos = start;
endPos = end;
return true ;
}
if (s[start] != t[start]) {
currCost -= conversionCost;
}
start++;
end++;
}
else {
end++;
}
}
return false ;
}
void validSubstring(string source, string target,
int conversionCost, int maxCost)
{
int low = 1;
int high = source.size();
while (low <= high) {
int mid = (low + high) / 2;
if (isValid(mid, source, target, conversionCost,
maxCost)) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
if (startPos == -1)
cout << "Not possible\n";
else
cout << startPos << " " << endPos << "\n";
}
int main()
{
string source = "adcf", target = "cdef";
int conversionCost = 3, maxCost = 5;
validSubstring(source, target, conversionCost, maxCost);
return 0;
}
|
Java
class GFG {
static int startPos = - 1 , endPos = - 1 ;
static boolean isValid( int len, String s, String t,
int conversionCost, int maxCost)
{
int start = 0 , end = 0 , n = s.length();
int currCost = 0 ;
while (end < n) {
if (s.charAt(end) != t.charAt(end)) {
currCost += conversionCost;
}
if (end - start + 1 == len) {
if (currCost <= maxCost) {
startPos = start;
endPos = end;
return true ;
}
if (s.charAt(start) != t.charAt(start)) {
currCost -= conversionCost;
}
start++;
end++;
}
else {
end++;
}
}
return false ;
}
static void validSubstring(String source, String target,
int conversionCost,
int maxCost)
{
int low = 1 ;
int high = source.length();
while (low <= high) {
int mid = (low + high) / 2 ;
if (isValid(mid, source, target, conversionCost,
maxCost)) {
low = mid + 1 ;
}
else {
high = mid - 1 ;
}
}
if (startPos == - 1 )
System.out.println( "Not possible\n" );
else
System.out.println(startPos + " " + endPos
+ "\n" );
}
public static void main(String[] args)
{
String source = "adcf" , target = "cdef" ;
int conversionCost = 3 , maxCost = 5 ;
validSubstring(source, target, conversionCost,
maxCost);
}
}
|
Python3
def is_valid(length, s, t, conversion_cost, max_cost):
global start_pos, end_pos
start, end, n = 0 , 0 , len (s)
curr_cost = 0
while end < n:
if s[end] ! = t[end]:
curr_cost + = conversion_cost
if end - start + 1 = = length:
if curr_cost < = max_cost:
start_pos = start
end_pos = end
return True
if s[start] ! = t[start]:
curr_cost - = conversion_cost
start + = 1
end + = 1
else :
end + = 1
return False
def valid_substring(source, target, conversion_cost, max_cost):
global start_pos, end_pos
low = 1
high = len (source)
while low < = high:
mid = (low + high) / / 2
if is_valid(mid, source, target, conversion_cost, max_cost):
low = mid + 1
else :
high = mid - 1
if start_pos = = - 1 :
print ( "Not possible" )
else :
print (f "{start_pos} {end_pos}" )
source_str = "adcf"
target_str = "cdef"
conversion_cost_val = 3
max_cost_val = 5
start_pos, end_pos = - 1 , - 1
valid_substring(source_str, target_str, conversion_cost_val, max_cost_val)
|
C#
using System;
class GFG
{
static int startPos = -1, endPos = -1;
static bool IsValid( int len, string s, string t,
int conversionCost, int maxCost)
{
int start = 0, end = 0, n = s.Length;
int currCost = 0;
while (end < n)
{
if (s[end] != t[end])
{
currCost += conversionCost;
}
if (end - start + 1 == len)
{
if (currCost <= maxCost)
{
startPos = start;
endPos = end;
return true ;
}
if (s[start] != t[start])
{
currCost -= conversionCost;
}
start++;
end++;
}
else
{
end++;
}
}
return false ;
}
static void ValidSubstring( string source, string target,
int conversionCost,
int maxCost)
{
int low = 1;
int high = source.Length;
while (low <= high)
{
int mid = (low + high) / 2;
if (IsValid(mid, source, target, conversionCost,
maxCost))
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
if (startPos == -1)
Console.WriteLine( "Not possible\n" );
else
Console.WriteLine(startPos + " " + endPos
+ "\n" );
}
public static void Main( string [] args)
{
string source = "adcf" , target = "cdef" ;
int conversionCost = 3, maxCost = 5;
ValidSubstring(source, target, conversionCost,
maxCost);
}
}
|
Javascript
let startPos = -1, endPos = -1;
function isValid(len, s, t, conversionCost, maxCost) {
let start = 0, end = 0, n = s.length;
let currCost = 0;
while (end < n) {
if (s[end] !== t[end]) {
currCost += conversionCost;
}
if (end - start + 1 === len) {
if (currCost <= maxCost) {
startPos = start;
endPos = end;
return true ;
}
if (s[start] !== t[start]) {
currCost -= conversionCost;
}
start++;
end++;
}
else {
end++;
}
}
return false ;
}
function validSubstring(source, target, conversionCost, maxCost) {
let low = 1;
let high = source.length;
while (low <= high) {
let mid = Math.floor((low + high) / 2);
if (isValid(mid, source, target, conversionCost, maxCost)) {
low = mid + 1;
} else {
high = mid - 1;
}
}
if (startPos === -1)
console.log( "Not possible" );
else
console.log(startPos + " " + endPos);
}
let source = "adcf" , target = "cdef" ;
let conversionCost = 3, maxCost = 5;
validSubstring(source, target, conversionCost, maxCost);
|
Time Complexity: O(N* log(N)) Auxiliary Space: O(1)
|