Introducción

1

Arrays y Strings para resolver algoritmos avanzados

2

Arrays y Strings en detalle

Dos Apuntadores

3

Patrón de Dos Apuntadores

4

Verifying Alien Dictionary: análisis del problema

5

Solución de Verifying Alien Dictionary

6

Playground: Verifying Alien Dictionary

7

Programando Verifying Alien Dictionary con JavaScript

8

Merge Two Sorted Lists: análisis del problema

9

Solución de Merge Two Sorted Lists

10

Playground: Merge Two Sorted Lists

11

Programando Merge Two Sorted Lists con Python

12

Container With Most Water: análisis del problema

13

Solución de Container With Most Water

14

Playground: Container with Most Water

15

Programando Container With Most Water con Java

16

Reto: Trapping Rain Water

17

Ejercicios recomendados de Dos Apuntadores

18

Ejercicios resueltos de Dos Apuntadores

Ventana Deslizante

19

Patrón de Ventana Deslizante

20

Longest Substring Without Repeating Characters: análisis del problema

21

Solución de Longest Substring Without Repeating Characters

22

Playground: Longest Substring Without Repeating Characters

23

Programando Longest Substring Without Repeating Characters con Python

24

Ejercicios recomendados de Ventana Deslizante

25

Ejercicios resueltos de Ventana Deslizante

Búsqueda Binaria

26

Algoritmo de Búsqueda Binaria

27

Search in Rotated Arrays: análisis del problema

28

Solución de Search in Rotated Arrays

29

Playground: Search in Rotated Arrays

30

Programando Search in Rotated Arrays

31

Search 2D Array Matrix: análisis del problema

32

Solución de Search 2D Array Matrix

33

Playground: Search 2D Array Matrix

34

Programando Search 2D Array Matrix

Próximos pasos

35

Toma el Curso Avanzado de Algoritmos: Estructuras de Datos Lineales

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Solución de Longest Substring Without Repeating Characters

21/35
Recursos

Aportes 8

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Aporto mi posible solución:

    public static int LongestSubStringWithoutRepeat(string text)
    {
        var hash = new HashSet<char>();
        int count = 0;
        int max = 0;
        int p = 0;

        while (text.Length > p)
        {
            if (!hash.Contains(text[p]))
            {
                hash.Add(text[p]);
                count++;
                p++;
            }
            else
            {
                if (count > max) max = count;
                hash.Clear();
                count = 0;
            }
        }
        if (count > max) max = count;
        return max;
    }

El p2 como se mueve constante con enumerate() funciona. El usar max o min no afecta la Big O. El p2 - p1 + 1 es porque es inclusivo y toca tener en cuenta el valor inicial y final.

Propongo mi solución en Python antes de ver el vídeo: ``` def longest\_substring\_without\_repeating\_characters(text) -> int: if len(text) == 0: return 0 seen = \[] p1, p2, longitud, longitud\_maxima = 0,0,0,0 while p2 < len(text) - 1: if text\[p2] not in seen: seen.append(text\[p2]) p2 += 1 if text\[p2] in seen: p1 = p2 longitud = len(seen) if longitud > longitud\_maxima: longitud\_maxima = longitud seen.clear() return longitud\_maxima if *\_\_name\_\_* == '\_\_main\_\_': print(longest\_substring\_without\_repeating\_characters("abcabcbbz")) #\* 3 print(longest\_substring\_without\_repeating\_characters("jdkafnlcdsalkxcmpoiuytfccv")) #\* 15 ```
**Otra posible solución con set seria la siguiente** Empezamos con un set vacio { } MaxLen = 0 checamos si la letra a la que apunta el p2 esta en el set, si no pues la agregamos y movemos p2 e incializamos una variable para almacenar la mayor longitud que empieza en 0 llamada MaxLen {”a”} MaxLen = 1 {”a”,”b”} MaxLen = 2 {”a”,”b”,”c”} MaxLen = 3 al encontrar una letra repetida, p1 va a eliminar la letra a la que esta apuntando y moverse un lugar y p2 tambien se mueve {”b”,”c”} MaxLen = 3 {”c”} MaxLen = 3 { } MaxLen = 3 llenando y vaciando el set según la repetición de las letras y quedándonos con la mayor longitud de la cadena encontrada, para al final devolverla.

Siempre me puso a pensar en muchas formas, pero esta es una posible solución


    // a, b, c, a, b, c, b, b
    public int countWithoutRepeating (String s) {
        if (s.length() < 2) return 0;

        int currentCount = 0;
        int maxCount = 0;

        int pointerA = 0;
        int pointerB = 0;

        for (int i = 0; i < s.toCharArray().length; i++) {
            // B

            boolean repeated = false;
            int j = pointerA; // 6
            // 6 < 7
            while (j < pointerB) {
                // b == b
                if (s.charAt(j) == s.charAt(i)) {
                    repeated = true;
                    break;
                }

                j++;
            }

            // 3 --> 3, 1
            maxCount = Math.max(maxCount, currentCount);

            // true
            if (repeated) {
                currentCount = 0;
                pointerA = pointerB; // 7
            }

            currentCount++; // 1
            pointerB++; // 8
        }

        return maxCount;
    }

Test.

public class LongestSubstringTest {

    LongestSubstring object = new LongestSubstring();

    @Test
    public void shouldBeThreeByABC () {
        String s = "abcabcbb";
        assertEquals(3,object.countWithoutRepeating(s));
    }

    @Test
    public void shouldBeFifteen () {
        String s = "jdkafnlcdsalkxcmpoiuytfccv";
        assertEquals(15,object.countWithoutRepeating(s));
    }

}

Lo mas enredado es saber cuando mover el pointer que casi no se mueve hehe:

Mi solucion en TypeScript:

export const longestSubstringWithoutRepeatingChars = (s: string): number => {
  let substring: { [key: string]: number } = {};
  let prevMaxValue = 0;
  let p1 = 0;
  let p2 = 0;

  while (p2 < s.length) {
    const char = s[p2];

    if (substring[char] !== undefined) {
      if (substring[char] >= p1) {
        prevMaxValue = Math.max(prevMaxValue, (p2 - p1));

        p1 = substring[char] + 1;
        substring[char] = p2;
        p2++;
      } else {
        substring[char] = p2;
        p2++;
      }
    } else {
      substring[char] = p2;
      p2++;
    }
  }

  return Math.max(prevMaxValue, (p2 - p1));
};
def longest_sub_without_repeating_chars(txt):
    # Pueden haber duplicados en este contexto.
    # Todo se convierte a mínusculas.
    l_txt = list(txt)
    ap1 = 0 # Apunta al inicio de la subcadena más larga
    ap2 = 0 # Apunta al final de la subcadena más larga
    dict_comb = {} # Almacena el índice de las letras por cada subcadena
    mayor_tam = 1 # Mayor tamaño a retornar

    while ap2 < len(l_txt):
        if l_txt[ap2] in dict_comb:
            if ap2 - ap1 > mayor_tam:
                mayor_tam = ap2 - ap1

            ap1 = ap2
            dict_comb = {} # Vaciar el diccionario para guardar los índices
            #  de la siguiente subcadena

        dict_comb[l_txt[ap2]] = ap2
        ap2 += 1

    return mayor_tam

    # Si por ejemplo tenemos una solución que en espacio es o(n^2), pero
    #  en performance es rápida, es bueno preguntar al entrevistador si
    #  está bien presentarla así. Es decir cual es el atributo de calidad a
    #  priorizar

txt = "abcabcbb"
sal = longest_sub_without_repeating_chars(txt)
print(sal)

txt = "jdkafnlcdsalkxcmpoiuytfccv"
sal = longest_sub_without_repeating_chars(txt)
print(sal)

txt = "jdkafnlcdsalkxcmpoiuytfavadswlkxcmpoiuytfñazadsalkxcmpoiuytf"
sal = longest_sub_without_repeating_chars(txt)
print(sal)

comparto mis solución en JS:

function longestSubstring(s){
    let p1 = 0
        p2 = p1 + 1
        subString = s[p1]
        largestLength = 0

    while(p2 < s.length) {
        if(subString.includes(s[p2])){
            p1 = p2
            p2 = p1 + 1
            subString = s[p1]
        } else {
            subString = subString + s[p2]
            p2++

            if(subString.length > largestLength){
                largestLength = subString.length
            }
        }

    }

    return largestLength
}