Principiantes: arreglos y cadenas

Objetivo

1. Comprender la diferencia entre arreglos y arreglos dinámicos.

2. Familiarizarse con las operaciones básicas en arreglos y arreglos dinámicos.

3. Comprender los arreglos multidimensionales y ser capaz de dominar el uso de arreglos bidimensionales.

4. Comprender el concepto de cuerdas y las diferentes características de las cuerdas.

5. Ser capaz de utilizar la técnica del doble puntero para la resolución de problemas prácticos.

Introducción a las matrices

数组Es una estructura de datos básica utilizada para ordenar por 存储元素的集合. Pero se puede acceder a los elementos aleatoriamente porque cada elemento de la matriz se puede 索引identificar por la matriz.

Los arreglos pueden tener una o más dimensiones. Aquí 一维数组comenzamos con , que también se conoce como matriz lineal.

Introducción a las matrices dinámicas

Las matrices tienen 固定的容量, necesitamos especificar el tamaño de la matriz en el momento de la inicialización. A veces puede ser muy inconveniente y potencialmente un desperdicio.

Como tal, la mayoría de los lenguajes de programación proporcionan un 动态数组, que sigue siendo una estructura de datos de lista de acceso aleatorio, pero 大小是可变的.

Encuentra el índice medio de una matriz

Dada una matriz de tipos enteros  nums, escriba un método que devuelva el "índice central" de la matriz.

Definimos el índice del centro del arreglo así : la suma de todos los elementos a la izquierda del índice del centro del arreglo es igual a la suma de todos los elementos a la derecha.

Si la matriz no tiene un índice central, entonces deberíamos devolver -1. Si la matriz tiene más de un índice central, debemos devolver el más cercano a la izquierda.

Ejemplo 1:

输入: 
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释: 
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。

Ejemplo 2:

输入: 
nums = [1, 2, 3]
输出: -1
解释: 
数组中不存在满足此条件的中心索引。

ilustrar:

  • nums El rango de longitud es  [0, 10000].
  • Cualquiera de los dos  nums[i] será un  [-1000, 1000]número entero en el rango.
class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        if len(nums) < 3:
            return -1
        for i in range(len(nums)):
            if sum(nums[:i]) == sum(nums[i+1:]):
                return i
        return -1
        

El número más grande que es al menos el doble de los otros datos

En una matriz dada nums, siempre hay un elemento máximo.

Encuentra si el elemento más grande en una matriz es al menos el doble de cualquier otro número en la matriz.

En caso afirmativo, devuelve el índice del elemento más grande; de ​​lo contrario, -1.

Ejemplo 1:

输入: nums = [3, 6, 1, 0]
输出: 1
解释: 6是最大的整数, 对于数组中的其他整数,
6大于数组中其他元素的两倍。6的索引是1, 所以我们返回1.

 

Ejemplo 2:

输入: nums = [1, 2, 3, 4]
输出: -1
解释: 4没有超过3的两倍大, 所以我们返回 -1.

 

pista:

  1. nums El rango de longitud es [1, 50].
  2. Cada  nums[i] número entero oscila entre  [0, 100].
class Solution:
    def dominantIndex(self, nums: List[int]) -> int:
        nums_max = max(nums)
        ind = nums.index(nums_max)
        tmp = []
        for item in nums:
            if nums_max >= 2 * item or item == nums_max:
                tmp.append(item)
        if len(tmp) == len(nums) :
            return ind
        else:
            return -1

mas uno

Dado un número entero no negativo representado por una matriz no vacía de números enteros, agregue uno al número .

El dígito más alto se almacena en la cabeza de la matriz, y cada elemento de la matriz almacena solo un número.

Puede suponer que este entero no comenzará con un cero que no sea el entero 0.

Ejemplo 1:

输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。

Ejemplo 2:

输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        n=len(digits)
        for i in range(n-1,-1,-1):
            if digits[i]<9:
                digits[i]+=1
                return digits
            else:
                digits[i]=0
        return [1]+digits

posición de intercalación de búsqueda

Dada una matriz ordenada y un valor de destino, encuentre el valor de destino en la matriz y devuelva su índice. Si el valor de destino no existe en la matriz, devuelve la posición en la que se insertará en orden. Puede suponer que no hay elementos duplicados en la matriz.

Ejemplo 1:

输入: [1,3,5,6], 5
输出: 2
class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        for i in range(0, len(nums)):
            if nums[i] >= target:
                return i
            elif i == len(nums) - 1:
                return len(nums)

intervalo de fusión

Dado un conjunto de intervalos, combine todos los intervalos superpuestos.

Ejemplo 1:

输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        res = []
        intervals.sort()
        for i in intervals:
            if not res or res[-1][1]<i[0]:
                res.append(i)
            else:
                res[-1][1] = max(res[-1][1],i[1])
        return res

Introducción a los datos 2D

Las matrices multidimensionales son más adecuadas para estructuras complejas como tablas o matrices.

objetivo de aprendizaje:

1. ¿Cómo se almacena en la memoria una matriz bidimensional?

2. Cómo usar arreglos bidimensionales para resolver problemas

matriz de rotación

Se le da una  N × N imagen representada por una matriz donde cada píxel tiene un tamaño de 4 bytes. Diseñe un algoritmo para rotar la imagen 90 grados.

¿Se puede hacer sin ocupar espacio de memoria adicional?

Ejemplo 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]
class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        n = len(matrix)
        # 先上下镜面翻转
        for i in range(n // 2):
            for j in range(n):
                matrix[i][j], matrix[n - 1 - i][j] = matrix[n - 1 - i][j], matrix[i][j]
        
        # 再主对角线翻转
        for i in range(n):
            for j in range(i):
                matrix[j][i], matrix[i][j] = matrix[i][j], matrix[j][i]

matriz cero

Escriba un algoritmo para borrar la fila y la columna donde un elemento en una matriz M × N es 0.

Ejemplo 1:

Entrada:
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
Salida:
[
  [1,0,1],
  [0,0,0],
  [1,0 ,1]
]

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        rownum = len(matrix)
        colnum = len(matrix[0])
        row = [False for i in range(rownum)]
        col = [False for i in range(colnum)]
        for i in range(rownum):
            for j in range(colnum):
                if matrix[i][j] == 0:
                    row[i] = True
                    col[j] = True
        for i in range(rownum):
            for j in range(colnum):
                if row[i] or col[j]:
                    matrix[i][j] = 0

recorrido diagonal

Dada una matriz con M x N elementos (M filas, N columnas), devuelva todos los elementos de esta matriz en el orden de recorrido diagonal, como se muestra en la siguiente figura.

 

Ejemplo:

Entrada:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

Salida: [1,2,4,7,5,3,6,8,9]

explicar:


Autor: LeetCode
Enlace: https://leetcode-cn.com/leetbook/read/array-and-string/cuxq3/
Fuente: LeetCode
Los derechos de autor pertenecen al autor. Para reimpresión comercial, comuníquese con el autor para obtener autorización, para reimpresión no comercial, indique la fuente.

class Solution:
    def findDiagonalOrder(self, matrix: List[List[int]]) -> List[int]:
        m = len(matrix)
        if not m:
            return []
        n = len(matrix[0])
        if not n:
            return []
        matrix_num = m*n
 
        count = 0
        x = y = 0
        li = []
        direction = "up"
        while count < matrix_num:
            count += 1
            li.append(matrix[x][y])
            # 右上方向
            if direction == "up":
                # 无需调换方向的条件(1.x>0 碰到上壁前, 2.y<n-1碰到右壁前)
                if x > 0 and y < n-1:
                     x -= 1
                     y += 1
                     continue
                else:
                    direction = "down"
                    # 碰到上壁 x=0
                    if x == 0 and y < n-1:
                        y += 1
                    # 碰到右壁
                    elif y == n-1:
                        x += 1
            # 左下方向
            else:
                # 无需调换方向的条件(1.x<m 碰到下壁前, 2.y>0 碰到右壁前)
                if x < m-1 and y > 0:
                    x += 1
                    y -= 1
                    continue
                else:
                    direction = "up"
                    if x == m-1:
                        y += 1
                    elif y == 0 and x < m-1:
                        x += 1
        return li

Introducción a las cadenas

Una cadena es una matriz de caracteres.

objetivo de aprendizaje:

1. Estar familiarizado con las operaciones básicas en cadenas, especialmente las operaciones únicas que no están disponibles en matrices
2. Comprender las diferencias entre diferentes funciones de comparación
3. Comprender si las cadenas son mutables y causan problemas en el proceso de conexión
4. Capaz para resolver problemas básicos relacionados con cadenas, como clasificación, subcadenas, coincidencia de cadenas, etc.

prefijo común más largo

Escriba una función para encontrar el prefijo común más largo en una matriz de cadenas.

Devuelve la cadena vacía "" si no existe un prefijo común.

Ejemplo 1:

Entrada: ["flor","flujo","vuelo"]
Salida: "fl"
Ejemplo 2:

Entrada: ["perro","carro de carreras","coche"]
Salida: ""
Explicación: No hay un prefijo común para la entrada.
ilustrar:

Todas las entradas contienen solo letras minúsculas az .

Autor: LeetCode
Enlace: https://leetcode-cn.com/leetbook/read/array-and-string/ceda1/
Fuente: LeetCode
Los derechos de autor pertenecen al autor. Para reimpresión comercial, comuníquese con el autor para obtener autorización, para reimpresión no comercial, indique la fuente.

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        import os
        return os.path.commonprefix(strs)

subcadena palindrómica más larga

Dada una cadena s, encuentre la subcadena palindrómica más larga en s. Puede suponer que s tiene una longitud máxima de 1000.

Ejemplo 1:

Entrada: "babad"
Salida: "bab"
Nota: "aba" también es una respuesta válida.
Ejemplo 2:

Entrada: "cbbd"
Salida: "bb"

Autor: LeetCode
Enlace: https://leetcode-cn.com/leetbook/read/array-and-string/conm7/
Fuente: LeetCode
Los derechos de autor pertenecen al autor. Para reimpresión comercial, comuníquese con el autor para obtener autorización, para reimpresión no comercial, indique la fuente.

class Solution:
    def longestPalindrome(self, s: str) -> str:
        max_length = 0
        start = 0
        for i in range(len(s)):
            if i - max_length >= 1 and s[i-max_length-1: i+1] == s[i-max_length-1: i+1][::-1]:
                start = i - max_length - 1
                max_length +=2
                continue
            if i - max_length >= 0 and s[i-max_length: i+1] == s[i-max_length: i+1][::-1]:
                start = i - max_length
                max_length += 1
        return s[start: start+max_length]

voltear palabras en una cadena

Dada una cadena, voltea cada palabra de la cadena una por una.

 

Ejemplo 1:

Entrada: " the sky is blue"
 Salida:  " blue is sky the"
class Solution:
    def reverseWords(self, s: str) -> str:
        li = s.split(" ")
        str = ""
        for i in range(len(li)-1, -1, -1):
            if li[i]:
                str = str + li[i] + " "
        # 因为最后一个单词多加了一个空格符“ ”          
        return str[:-1] 

Algoritmo de coincidencia de cadenas: KMP

El algoritmo Knuth-Morris-Pratt (KMP) es un algoritmo de coincidencia de cadenas mejorado. Su núcleo es utilizar la información después de que falla la coincidencia para minimizar el número de coincidencias entre la cadena patrón y la cadena principal para lograr el propósito de una coincidencia rápida. Su complejidad temporal es O(m+n)O(m+n)O(m+n).

int match (char* P, char* S){ // KMP 算法
    int* next = buildNext(P); // 构造 next 表
    int m = (int) strlen (S), i = 0; // 文本串指针
    int n = (int) strlen(P), j = 0; //模式串指针
    while (j < n && i < m) // 自左向右逐个比对字符
        if (0 > j || S[i] == P[j]) // 若匹配,或 P 已移除最左侧
            {i++; j++} // 则转到下一字符
        else
            j = next[j]; // 模式串右移(注意:文本串不用回退)
    delete [] next; // 释放 next 表
    return i - j;
}

Implementar strStr()

Implemente la función strStr().

Dada una cuerda de pajar y una cuerda de agujas, encuentre la primera posición (a partir de 0) de la cuerda de agujas en la cuerda de pajar. Devuelve -1 si no está presente.

Ejemplo 1:

Entrada: pajar = "hola", aguja = "ll"
Salida: 2
Ejemplo 2:

Entrada: pajar = "aaaa", aguja = "bba"
Salida: -1
Explicación:

¿Qué debemos devolver cuando la aguja es una cadena vacía? Esta es una gran pregunta para hacer en una entrevista.

Para esta pregunta, debemos devolver 0 cuando la aguja es una cadena vacía. Esto coincide con la definición de strstr() en C e indexOf() en Java.

Autor: LeetCode
Enlace: https://leetcode-cn.com/leetbook/read/array-and-string/cm5e2/
Fuente: LeetCode
Los derechos de autor pertenecen al autor. Para reimpresión comercial, comuníquese con el autor para obtener autorización, para reimpresión no comercial, indique la fuente.

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        for i in range(0, len(haystack) - len(needle) + 1):
            if haystack[i: i + len(needle)] == needle:
                return i
        return -1

técnica de dos puntos

Técnica de dos punteros Escenario 1

Invierte los elementos de la matriz. Por ejemplo, la matriz es ['l', 'e', ​​'e', ​​'t', 'c', 'o', 'd', 'e'], después de la inversión se convierte en ['e ', 'd', 'o', 'c', 't', 'e', ​​'e', ​​'l'].

def reverseString(self, s):
        i, j = 0, len(s) - 1
        while i < j:
            s[i], s[j] = s[j], s[i]
            i += 1
            j -= 1

cadena inversa

Escriba una función que invierta la cadena de entrada. La cadena de entrada se proporciona como una matriz de caracteres char[].

No asigne espacio adicional para otra matriz, debe modificar la matriz de entrada en el lugar, utilizando O (1) espacio adicional para resolver este problema.

Puede suponer que todos los caracteres de la matriz son caracteres imprimibles en la tabla de códigos ASCII.

 

Ejemplo 1:

Entrada: ["h","e","l","l","o"]
Salida: ["o","l","l","e","h"]
Ejemplo 2:

Texto:["H","a","n","n","a","h"] Texto:[
"h","a","n","n","a", "H"]

Autor: LeetCode
Enlace: https://leetcode-cn.com/leetbook/read/array-and-string/cacxi/
Fuente: LeetCode
Los derechos de autor pertenecen al autor. Para reimpresión comercial, comuníquese con el autor para obtener autorización, para reimpresión no comercial, indique la fuente.

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        j=-1
        for i in range(0,len(s)//2):
            t=s[i]
            s[i]=s[j]
            s[j]=t
            j-=1

Técnica de doble puntero Escenario 2

Use dos punteros no sincronizados para resolver el problema, los punteros rápido y lento.

ejemplo


Comencemos con un problema clásico:

Dada una matriz  nums y un valor  val, debe   eliminar todos los elementos iguales al valor  en lugarval  y devolver la nueva longitud de la matriz eliminada.

 

def removeElement(self, nums: List[int], val: int) -> int:
    slow = 0
    n = len(nums)
    for fast in range(n):
        if nums[fast] != val:
            nums[slow] = nums[fast]
            slow += 1
    return slow

eliminar elemento

Dada una matriz nums y un valor val, debe eliminar todos los elementos cuyo valor sea igual a val en su lugar y devolver la nueva longitud de la matriz eliminada.

No use espacio adicional en la matriz, debe usar solo O (1) espacio adicional y modificar la matriz de entrada en el lugar.

El orden de los elementos se puede cambiar. No necesita considerar elementos en la matriz más allá de la nueva longitud.

 

Ejemplo 1:

Números dados = [3,2,2,3], val = 3,

La función debería devolver la nueva longitud 2, y los dos primeros elementos en nums son ambos 2.

No necesita considerar elementos en la matriz más allá de la nueva longitud.

ilustrar:

¿Por qué el valor devuelto es un número entero, pero la respuesta de salida es una matriz?

Tenga en cuenta que la matriz de entrada se pasa "por referencia", lo que significa que las modificaciones a la matriz de entrada dentro de la función son visibles para la persona que llama.

Puedes imaginar el funcionamiento interno de la siguiente manera:

// nums se pasa por "referencia". Es decir, no haga ninguna copia de los parámetros reales
int len ​​​​= removeElement(nums, val);

// Las modificaciones a la matriz de entrada en la función son visibles para la persona que llama.
// Dependiendo de la longitud devuelta por su función, imprimirá todos los elementos de la matriz dentro de esa longitud.
for (int i = 0; i < len; i++) {     print(nums[i]); }

Autor: LeetCode
Enlace: https://leetcode-cn.com/leetbook/read/array-and-string/cwuyj/
Fuente: LeetCode
Los derechos de autor pertenecen al autor. Para reimpresión comercial, comuníquese con el autor para obtener autorización, para reimpresión no comercial, indique la fuente.

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        while val in nums:
            nums.remove(val)
        return len(nums)

resumen

Tecnologías relacionadas con arreglos

1, aquí hay algunas otras estructuras de datos similares a matrices, pero con algunas propiedades diferentes:

String
Hash Table
Linked List
Queue
Stack
2, como mencionamos, podemos llamar a funciones integradas para ordenar la matriz. Sin embargo, es útil comprender los principios de algunos algoritmos de clasificación ampliamente utilizados y sus complejidades.

3. La búsqueda binaria también es una técnica importante para buscar un elemento específico en una matriz ordenada.

4. Hemos introducido la técnica del doble puntero en este capítulo. No es fácil utilizar esta técnica de forma flexible. Este truco también se puede utilizar para resolver:

El problema del puntero lento y el puntero rápido en la lista enlazada
Problema de la ventana deslizante
5, la técnica del doble puntero a veces se relaciona con el algoritmo voraz, que puede ayudarnos a diseñar la estrategia de movimiento del puntero. 

Supongo que te gusta

Origin blog.csdn.net/weixin_42748604/article/details/106097306
Recomendado
Clasificación