Notas de revisión de preguntas "Notas aleatorias de código": Capítulo de matriz [implementación de Java]

*Búsqueda binaria

Enlace de pregunta

https://leetcode.cn/problems/binary-search/

Implementación de intervalos cerrados a la izquierda y cerrados a la derecha.

  • Complejidad del tiempo: O (log n)
  • Complejidad espacial: O (1)
/**
 * 左闭右闭写法
 *
 * @param nums
 * @param target
 * @return
 */
public static int search1(int[] nums, int target) {
    
    
    if (nums == null || nums.length == 0) {
    
    
        return -1;
    }
    int left = 0;
    int right = nums.length - 1;
    // 要是没有等号的话,在{5}里面找5就会出问题了
    while (left <= right) {
    
    
        int center = (left + right) / 2;
        if (target == nums[center]) {
    
    
            return center;
        } else if (target > nums[center]) {
    
    
            left = center + 1;
        } else {
    
    
            right = center - 1;
        }
    }
    return -1;
}

Implementación de intervalo cerrado por la izquierda y abierto por la derecha.

  • Complejidad del tiempo: O (log n)
  • Complejidad espacial: O (1)
/**
 * 左闭右开写法
 *
 * @param nums
 * @param target
 * @return
 */
public static int search2(int[] nums, int target) {
    
    
    if (nums == null || nums.length == 0) {
    
    
        return -1;
    }
    int left = 0;
    // 区别点
    int right = nums.length;
    // 区别点
    while (left < right) {
    
    
        int center = (left + right) / 2;
        if (target == nums[center]) {
    
    
            return center;
        } else if (target > nums[center]) {
    
    
            left = center + 1;
        } else {
    
    
            // 区别点
            // 虽然已经知道center位置的元素不是要找的元素,但是因为是左闭右开,因此right还是指向center
            // 后面无论怎么循环,都不会再使用到center这个为止,因为center = (left + right) / 2永远小于right
            right = center;
        }
    }
    return -1;
}

*eliminar elemento

Enlace de pregunta

https://leetcode.cn/problems/remove-element/

Solución violenta

  • Complejidad del tiempo: O (n ^ 2)
  • Complejidad espacial: O (1)
public static int removeElement(int[] nums, int val) {
    
    
    int sameNum = 0;
    int i = 0;
    while (i < nums.length - sameNum) {
    
    
        if (val == nums[i]) {
    
    
            // 将后面的元素前移过来
            for (int j = i; j < nums.length - 1 - sameNum; j++) {
    
    
                nums[j] = nums[j + 1];
            }
            sameNum++;
        }
        if (val == nums[i]) {
    
    
            // 前移过来的数值和val一样,将i--
            i--;
        }
        i++;
    }
    return nums.length - sameNum;
}

doble puntero

  • Complejidad del tiempo: O (n)
  • Complejidad espacial: O (1)

【Pensamiento】

Complete el trabajo de dos bucles for bajo un bucle for a través de un puntero rápido y un puntero lento, y asigne el valor del puntero rápido al puntero lento.

lento: el índice del valor almacenado en la nueva matriz, porque cada vez que se almacena el valor de la nueva matriz, se agregará lento ++, por lo que al final, simplemente devuelva lento directamente y debe devolver lento + 1

rápido: se utiliza para explorar valores que no son val y luego asignar este valor a la posición correspondiente a lento

Insertar descripción de la imagen aquí

/**
 * 双指针
 *
 * @param nums
 * @param val
 * @return
 */
public static int removeElement1(int[] nums, int val) {
    
    
    int slow = 0;
    for (int fast = 0; fast < nums.length; fast++) {
    
    
        if (nums[fast] != val) {
    
    
            // 如果快指针找的数值不是val,就需要将其存储到新数组中
            // 同时slow++,以便存储下一个新数组的值
            nums[slow++] = nums[fast];
        }
    }
    return slow;
}

Método opuesto de dos punteros

  • Complejidad del tiempo: O (n)
  • Complejidad espacial: O (1)

El método de implementación anterior no cambia la posición relativa del elemento, el método de doble puntero opuesto cambia la posición relativa del elemento, pero garantiza que se mueva el menor elemento.

Insertar descripción de la imagen aquí

/**
 * 想向双指针
 *
 * @param nums
 * @param val
 * @return
 */
public static int removeElement(int[] nums, int val) {
    
    
    int slow = 0, fast = nums.length - 1;
    while (slow <= fast) {
    
    
        // slow赋值为第一个等于val的索引
        while (slow <= fast) {
    
    
            if (nums[slow] != val) {
    
    
                slow++;
            } else {
    
    
                break;
            }
        }
        // fast赋值为最后一个等于val的索引
        while (fast >= slow) {
    
    
            if (nums[fast] == val) {
    
    
                fast--;
            } else {
    
    
                break;
            }
        }
        if (slow < fast) {
    
    
            nums[slow++] = nums[fast--];
        }
    }
    // slow最后一定指向的是 新数组末尾元素的下一个元素
    return slow;
}

* Cuadrado de matriz ordenada

Enlace de pregunta

https://leetcode.cn/problems/squares-of-a-sorted-array/

Solución violenta

  1. Primero cuadra cada elemento de la matriz.
  2. Ordenar matriz en orden ascendente

Complejidad temporal: O (n) + complejidad temporal del algoritmo de clasificación

doble puntero

[ideas]

La matriz en sí está en orden no decreciente, pero los números negativos pueden volverse más grandes después de elevarlos al cuadrado, por lo que solo necesita comparar los dos extremos para saber qué número tiene un cuadrado más grande.

  • Complejidad del tiempo: O (n)
  • Complejidad espacial: O (n)

Insertar descripción de la imagen aquí

public static int[] sortedSquares(int[] nums) {
    
    
    int left = 0, right = nums.length - 1;
    // 用于存储排序之后的结果
    int[] result = new int[nums.length];
    for (int i = nums.length - 1; i >= 0; i--) {
    
    
        int leftValue = nums[left];
        int rightValue = nums[right];
        if (leftValue * leftValue >= rightValue * rightValue) {
    
    
            result[i] = leftValue * leftValue;
            left++;
        } else {
    
    
            result[i] = rightValue * rightValue;
            right--;
        }
        System.out.println(Arrays.toString(result));
    }
    return result;
}

*Subarreglo con longitud mínima

Enlace de pregunta

https://leetcode.cn/problems/minimum-size-subarray-sum/

Solución violenta

  • Complejidad del tiempo: O (n ^ 2)
  • Complejidad espacial: O (1)

Tenga en cuenta que una submatriz es una colección de elementos consecutivos en la matriz original.

public int minSubArrayLen(int target, int[] nums) {
    
    
    // 最小子数组长度
    int minLen = nums.length + 1;
    for (int i = 0; i < nums.length; i++) {
    
    
        int sum = 0;
        for (int j = i; j < nums.length; j++) {
    
    
            sum += nums[j];
            if (sum >= target) {
    
    
                // 已经>=target,可以暂停了
                if ((j - i + 1) < minLen) {
    
    
                    minLen = j - i + 1;
                    break;
                }
            }
        }
    }
    return minLen == nums.length + 1 ? 0 : minLen;
}

Algunos casos han excedido el límite de tiempo.

Insertar descripción de la imagen aquí

ventana deslizante

  • Complejidad del tiempo: O (n): no se puede pensar que poner un tiempo en for sea O (n ^ 2). Depende principalmente del número de veces que se opera cada elemento. Cada elemento entra y opera una vez después de la ventana deslizante y sale. una vez. Cada elemento se opera dos veces, por lo que la complejidad del tiempo es 2 × n, que es O (n)
  • Complejidad espacial: O (1)

Insertar descripción de la imagen aquí

/**
 * 滑动窗口
 *
 * @param target
 * @param nums
 * @return
 */
public int minSubArrayLen1(int target, int[] nums) {
    
    
    // 最小子数组长度
    int minLen = nums.length + 1;
    int i = 0;
    int sum = 0;
    for (int j = 0; j < nums.length; j++) {
    
    
        // j++,窗口终止位置后移一位,sum添加相应的元素
        sum += nums[j];
        while (sum >= target) {
    
    
            // 窗口内的元素总和已经超过target,尝试将窗口的起始位置后移,即i++
            if ((j - i + 1) < minLen) {
    
    
                minLen = j - i + 1;
            }
            // sum移除窗口起始位置的元素值
            sum -= nums[i++];
        }
    }
    return minLen == nums.length + 1 ? 0 : minLen;
}

matriz espiral

【Pensamiento】

Esta pregunta es principalmente para probar su capacidad de codificación. Tenga en cuenta que cada ciclo se deja abierto y se cierra a la derecha.

【Programa escrito por mí】

public static int[][] generateMatrix1(int n) {
    
    
    int[][] result = new int[n][n];
    int curNum = 1;
    int target = n * n;
    int initN = n;
    // 圈数
    int cirCleNum = 0;
    while (curNum <= target) {
    
    
        if (curNum == target) {
    
    
            result[cirCleNum][cirCleNum] = curNum;
            System.out.println("---------------------填中心---------------------");
            for (int i = 0; i < result.length; i++) {
    
    
                System.out.println(Arrays.toString(result[i]));
            }
            break;
        }
        // 填上边
        for (int i = 0; i < n - 1; i++) {
    
    
            result[cirCleNum][i + cirCleNum] = curNum++;
        }
        System.out.println("---------------------填上边---------------------");
        for (int i = 0; i < result.length; i++) {
    
    
            System.out.println(Arrays.toString(result[i]));
        }
        // 填右边
        for (int i = 0; i < n - 1; i++) {
    
    
            result[i + cirCleNum][initN - 1 - cirCleNum] = curNum++;
        }
        System.out.println("---------------------填右边---------------------");
        for (int i = 0; i < result.length; i++) {
    
    
            System.out.println(Arrays.toString(result[i]));
        }
        // 填下边
        for (int i = n - 1; i > 0; i--) {
    
    
            result[initN - 1 - cirCleNum][i + cirCleNum] = curNum++;
        }
        System.out.println("---------------------填下边---------------------");
        for (int i = 0; i < result.length; i++) {
    
    
            System.out.println(Arrays.toString(result[i]));
        }
        // 填左边
        for (int i = n - 1; i > 0; i--) {
    
    
            result[i + cirCleNum][cirCleNum] = curNum++;
        }
        System.out.println("---------------------填左边---------------------");
        for (int i = 0; i < result.length; i++) {
    
    
            System.out.println(Arrays.toString(result[i]));
        }
        System.out.println("======================================================================");
        cirCleNum += 1;
        n -= 2;

    }

    return result;
}

[Código de otras personas]

public int[][] generateMatrix(int n) {
    
    
    int loop = 0;  // 控制循环次数
    int[][] res = new int[n][n];
    int start = 0;  // 每次循环的开始点(start, start)
    int count = 1;  // 定义填充数字
    int i, j;

    while (loop++ < n / 2) {
    
     // 判断边界后,loop从1开始
        // 模拟上侧从左到右
        for (j = start; j < n - loop; j++) {
    
    
            res[start][j] = count++;
        }

        // 模拟右侧从上到下
        for (i = start; i < n - loop; i++) {
    
    
            res[i][j] = count++;
        }

        // 模拟下侧从右到左
        for (; j >= loop; j--) {
    
    
            res[i][j] = count++;
        }

        // 模拟左侧从下到上
        for (; i >= loop; i--) {
    
    
            res[i][j] = count++;
        }
        start++;
    }

    if (n % 2 == 1) {
    
    
        res[start][start] = count;
    }

    return res;
}

Supongo que te gusta

Origin blog.csdn.net/laodanqiu/article/details/132700207
Recomendado
Clasificación