Substring más larga con K caracteres únicos usando búsqueda binaria

Dada una string str y un entero K , la tarea es imprimir la longitud de la substring más larga posible que tenga exactamente K caracteres únicos. Si hay más de una substring de la mayor longitud posible, imprima cualquiera de ellas o imprima -1 si no existe tal substring posible.

Ejemplos: 

Entrada: str = “aabacbebebe”, K = 3 
Salida:
“cbebebe” es la substring requerida.

Entrada: str = “aabc”, K = 4 
Salida: -1 

Enfoque: En este artículo se ha discutido un enfoque para resolver este problema . En este artículo, se discutirá un enfoque basado en la búsqueda binaria . La búsqueda binaria se aplicará a la longitud de la substring que tenga al menos K caracteres únicos. Digamos que intentamos con la longitud len y verificamos si hay una substring de tamaño len que tenga al menos k caracteres únicos. Si es posible, intente maximizar el tamaño buscando esta longitud hasta la longitud máxima posible, es decir, el tamaño de la string de entrada. Si no es posible, busque una lente de menor tamaño. 
Para verificar que la longitud dada por la búsqueda binaria tendrá k caracteres únicos, se puede usar un conjunto para insertar todos los caracteres, y luego, si el tamaño del conjunto es menor que k, entonces la respuesta no es posible, de lo contrario, la respuesta dada por la búsqueda binaria es la respuesta máxima. 
La búsqueda binaria es aplicable aquí porque se sabe si para algún len la respuesta es posible y queremos maximizar el len para que el dominio de búsqueda cambie y busquemos desde este len hasta n.
A continuación se muestra la implementación del enfoque anterior:

C++

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that returns true if there
// is a substring of length len
// with <=k unique characters
bool isValidLen(string s, int len, int k)
{
 
    // Size of the string
    int n = s.size();
 
    // Map to store the characters
    // and their frequency
    unordered_map<char, int> mp;
    int right = 0;
 
    // Update the map for the
    // first substring
    while (right < len) {
        mp[s[right]]++;
        right++;
    }
 
    if (mp.size() <= k)
        return true;
 
    // Check for the rest of the substrings
    while (right < n) {
 
        // Add the new character
        mp[s[right]]++;
 
        // Remove the first character
        // of the previous window
        mp[s[right - len]]--;
 
        // Update the map
        if (mp[s[right - len]] == 0)
            mp.erase(s[right - len]);
        if (mp.size() <= k)
            return true;
        right++;
    }
    return mp.size() <= k;
}
 
// Function to return the length of the
// longest substring which has K
// unique characters
int maxLenSubStr(string s, int k)
{
 
    // Check if the complete string
    // contains K unique characters
    set<char> uni;
    for (auto x : s)
        uni.insert(x);
    if (uni.size() < k)
        return -1;
 
    // Size of the string
    int n = s.size();
 
    // Apply binary search
    int lo = -1, hi = n + 1;
    while (hi - lo > 1) {
        int mid = lo + hi >> 1;
        if (isValidLen(s, mid, k))
            lo = mid;
        else
            hi = mid;
    }
    return lo;
}
 
// Driver code
int main()
{
    string s = "aabacbebebe";
    int k = 3;
 
    cout << maxLenSubStr(s, k);
 
    return 0;
}

Java

// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
    // Function that returns true if there
    // is a subString of length len
    // with <=k unique characters
    static boolean isValidLen(String s,
                              int len, int k)
    {
 
        // Size of the String
        int n = s.length();
 
        // Map to store the characters
        // and their frequency
        Map<Character,
            Integer> mp = new HashMap<Character,
                                      Integer>();
        int right = 0;
 
        // Update the map for the
        // first subString
        while (right < len)
        {
            if (mp.containsKey(s.charAt(right)))
            {
                mp.put(s.charAt(right),
                mp.get(s.charAt(right)) + 1);
            }
            else
            {
                mp.put(s.charAt(right), 1);
            }
            right++;
        }
 
        if (mp.size() <= k)
            return true;
 
        // Check for the rest of the subStrings
        while (right < n)
        {
 
            // Add the new character
            if (mp.containsKey(s.charAt(right)))
            {
                mp.put(s.charAt(right),
                mp.get(s.charAt(right)) + 1);
            }
            else
            {
                mp.put(s.charAt(right), 1);
            }
 
            // Remove the first character
            // of the previous window
            if (mp.containsKey(s.charAt(right - len)))
            {
                mp.put(s.charAt(right - len),
                mp.get(s.charAt(right - len)) - 1);
            }
 
            // Update the map
            if (mp.get(s.charAt(right - len)) == 0)
                mp.remove(s.charAt(right - len));
            if (mp.size() <= k)
                return true;
            right++;
        }
        return mp.size() <= k;
    }
 
    // Function to return the length of the
    // longest subString which has K
    // unique characters
    static int maxLenSubStr(String s, int k)
    {
 
        // Check if the complete String
        // contains K unique characters
        Set<Character> uni = new HashSet<Character>();
        for (Character x : s.toCharArray())
            uni.add(x);
        if (uni.size() < k)
            return -1;
 
        // Size of the String
        int n = s.length();
 
        // Apply binary search
        int lo = -1, hi = n + 1;
        while (hi - lo > 1)
        {
            int mid = lo + hi >> 1;
            if (isValidLen(s, mid, k))
                lo = mid;
            else
                hi = mid;
        }
        return lo;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        String s = "aabacbebebe";
        int k = 3;
 
        System.out.print(maxLenSubStr(s, k));
    }
}
 
// This code is contributed by Rajput-Ji

Python3

# Python3 implementation of the approach
 
# Function that returns True if there
# is a sub of length len
# with <=k unique characters
def isValidLen(s, lenn, k):
 
    # Size of the
    n = len(s)
 
    # Map to store the characters
    # and their frequency
    mp = dict()
    right = 0
 
    # Update the map for the
    # first sub
    while (right < lenn):
        mp[s[right]] = mp.get(s[right], 0) + 1
        right += 1
 
    if (len(mp) <= k):
        return True
 
    # Check for the rest of the subs
    while (right < n):
 
        # Add the new character
        mp[s[right]] = mp.get(s[right], 0) + 1
 
        # Remove the first character
        # of the previous window
        mp[s[right - lenn]] -= 1
 
        # Update the map
        if (mp[s[right - lenn]] == 0):
            del mp[s[right - lenn]]
        if (len(mp) <= k):
            return True
        right += 1
 
    return len(mp)<= k
 
# Function to return the length of the
# longest sub which has K
# unique characters
def maxLenSubStr(s, k):
 
    # Check if the complete
    # contains K unique characters
    uni = dict()
    for x in s:
        uni[x] = 1
    if (len(uni) < k):
        return -1
 
    # Size of the
    n = len(s)
 
    # Apply binary search
    lo = -1
    hi = n + 1
    while (hi - lo > 1):
        mid = lo + hi >> 1
        if (isValidLen(s, mid, k)):
            lo = mid
        else:
            hi = mid
 
    return lo
 
# Driver code
s = "aabacbebebe"
k = 3
 
print(maxLenSubStr(s, k))
 
# This code is contributed by Mohit Kumar

C#

// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function that returns true if there
    // is a subString of length len
    // with <=k unique characters
    static bool isValidLen(String s,
                           int len, int k)
    {
 
        // Size of the String
        int n = s.Length;
 
        // Map to store the characters
        // and their frequency
        Dictionary<char,
                   int> mp = new Dictionary<char,
                                            int>();
        int right = 0;
 
        // Update the map for the
        // first subString
        while (right < len)
        {
            if (mp.ContainsKey(s[right]))
            {
                mp[s[right]] = mp[s[right]] + 1;
            }
            else
            {
                mp.Add(s[right], 1);
            }
            right++;
        }
 
        if (mp.Count <= k)
            return true;
 
        // Check for the rest of the subStrings
        while (right < n)
        {
 
            // Add the new character
            if (mp.ContainsKey(s[right]))
            {
                mp[s[right]] = mp[s[right]] + 1;
            }
            else
            {
                mp.Add(s[right], 1);
            }
 
            // Remove the first character
            // of the previous window
            if (mp.ContainsKey(s[right - len]))
            {
                mp[s[right - len]] = mp[s[right - len]] - 1;
            }
 
            // Update the map
            if (mp[s[right - len]] == 0)
                mp.Remove(s[right - len]);
            if (mp.Count <= k)
                return true;
            right++;
        }
        return mp.Count <= k;
    }
 
    // Function to return the length of the
    // longest subString which has K
    // unique characters
    static int maxLenSubStr(String s, int k)
    {
 
        // Check if the complete String
        // contains K unique characters
        HashSet<char> uni = new HashSet<char>();
        foreach (char x in s.ToCharArray())
            uni.Add(x);
        if (uni.Count < k)
            return -1;
 
        // Size of the String
        int n = s.Length;
 
        // Apply binary search
        int lo = -1, hi = n + 1;
        while (hi - lo > 1)
        {
            int mid = lo + hi >> 1;
            if (isValidLen(s, mid, k))
                lo = mid;
            else
                hi = mid;
        }
        return lo;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        String s = "aabacbebebe";
        int k = 3;
 
        Console.Write(maxLenSubStr(s, k));
    }
}
 
// This code is contributed by Rajput-Ji

Javascript

<script>
  
// Javascript implementation of the approach
 
// Function that returns true if there
// is a substring of length len
// with <=k unique characters
function isValidLen(s, len, k)
{
 
    // Size of the string
    var n = s.length;
 
    // Map to store the characters
    // and their frequency
    var mp = new Map();
    var right = 0;
 
    // Update the map for the
    // first substring
    while (right < len) {
        if(mp.has(s[right]))
            mp.set(s[right],mp.get(s[right])+1)
        else
            mp.set(s[right], 1)
        right++;
    }
 
    if (mp.size <= k)
        return true;
 
    // Check for the rest of the substrings
    while (right < n) {
 
        // Add the new character
        if(mp.has(s[right]))
            mp.set(s[right],mp.get(s[right])+1)
        else
            mp.set(s[right], 1)
 
        // Remove the first character
        // of the previous window
        if(mp.has(s[right - len]))
            mp.set(s[right - len], mp.get(s[right - len])-1)
 
        // Update the map
        if(mp.has(s[right - len]) && mp.get(s[right - len])==0)
            mp.delete(s[right - len]);
        if (mp.size <= k)
            return true;
        right++;
    }
    return mp.size <= k;
}
 
// Function to return the length of the
// longest substring which has K
// unique characters
function maxLenSubStr(s, k)
{
 
    // Check if the complete string
    // contains K unique characters
    var uni = new Set();
    s.split('').forEach(x => {
        uni.add(x);
    });
     
    if (uni.size < k)
        return -1;
 
    // Size of the string
    var n = s.length;
 
    // Apply binary search
    var lo = -1, hi = n + 1;
    while (hi - lo > 1) {
        var mid = lo + hi >> 1;
        if (isValidLen(s, mid, k))
            lo = mid;
        else
            hi = mid;
    }
    return lo;
}
 
// Driver code
var s = "aabacbebebe";
var k = 3;
document.write( maxLenSubStr(s, k));
 
</script>
Producción: 

7

 

Publicación traducida automáticamente

Artículo escrito por Dwngu y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *