[Entrenamiento de novatos] Sword se refiere a la Oferta 57. La suma son los dos números de s

Descripción del Título:

Ingrese una matriz en orden ascendente y un número s, y encuentre dos números en la matriz para que su suma sea exactamente s. Si la suma de varios pares de números es igual as, entonces genere cualquier par.

Ejemplo 1:
Entrada: nums = [2,7,11,15], objetivo = 9
Salida: [2,7] o [7,2]

Ejemplo 2:
Entrada: nums = [10,26,30,31,47,60], objetivo = 40
Salida: [10,30] o [30,10]

限制 :
1 <= nums.length <= 10 ^ 5
1 <= nums [i] <= 10 ^ 6

Fuente: LeetCode (LeetCode)
Enlace: https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof Los
derechos de autor son propiedad de LeetCode . Para reimpresiones comerciales, comuníquese con la autorización oficial. Para reimpresiones no comerciales, indique la fuente.

Ideas de resolución de problemas:

Método 1: búsqueda binaria. A través de las restricciones que da el tema, es obvio que el tema no se puede usar directamente de forma violenta, ni se puede hacer con ArrayList, que obviamente excederá el límite de tiempo. Por lo tanto, debemos tomar algunas medidas para reducir el costo de tiempo cuando buscamos otro número con un número conocido. Debido a que la matriz dada está ordenada, la dicotomía es un buen método. No se describirá el proceso específico de dicotomía.

Método dos: doble puntero. Debido a que la matriz dada está en orden, podemos usar dos punteros, un puntero apunta al extremo frontal de la matriz, es decir, nums [0], y un puntero apunta al último extremo de la matriz, es decir, nums [ nums.length-1].
De esta forma, asumiendo que los dos punteros son i y j respectivamente, obtenemos dos números en la matriz. Actualmente hay tres situaciones:
(1) Cuando nums [i] + nums [j] == target, esto significa que han encontrado Si se cumple una de las condiciones requeridas por el título, se puede finalizar el ciclo.
(2) Cuando nums [i] + nums [j]> objetivo, esto significa que el número al que apunta j es demasiado grande, por lo que también puede mover j un bit hacia la izquierda y continuar la comparación.
(3) Cuando nums [i] + nums [j] <objetivo, esto indica que el número señalado por i es demasiado pequeño, por lo que también puede mover i un lugar a la derecha y continuar la comparación.

¿Por qué se puede hacer esto? Porque la matriz está ordenada. Si i no cambia, la suma del número apuntado por j y el número apuntado por i es mayor que el objetivo, entonces el número en el extremo derecho de j y nums [ i] será más que objetivo si se agrega Big. Si j no cambia, la suma del número señalado por i y el número señalado por j es menor que el objetivo, entonces la suma del número en el extremo izquierdo de iy nums [j] debe ser mayor que el objetivo.

Nota: La complejidad temporal de la bisección es mucho mayor que la de los punteros duales.
Complejidad temporal del método de búsqueda binaria: O (nlogn)
Complejidad temporal del método de doble puntero: O (n)

Código detallado:

public class jianzhi_Offer_57 {
    
    
    public int[] twoSum(int[] nums, int target) {
    
    
        int[] ans = new int[2];
        int k = 0;
        for (int i = 0; i < nums.length; i++){
    
    
            if(search(nums, i, nums.length-1,target-nums[i]) == true) {
    
    
            	//此处的写法也可和方法二一样
                ans[k++] = nums[i];
                ans[k++] = target - nums[i];
                return ans;
            }
        }
        return ans;
    }
    //二分查找
   public boolean search(int[] nums, int l, int r,int target){
    
    
        boolean flag = false;
        if(l > r)
            return flag;
        int mid = (l + r) / 2;
        if (nums[mid] == target){
    
    
            flag = true;
        }
        else if(nums[mid] > target){
    
    
            flag = search(nums,l,mid - 1,target);
        }
        else{
    
    
            flag = search(nums,mid + 1, r,target);
        }
        return flag;
   }

    //双指针,一个指针指向数组的前部,一个指针指向数组的后部
    //当两个指针所在的数的和比target大时,后指针左移
    //当两个指针所在的数的和比target小时,前指针右移
    public int[] twoSum1(int[] nums, int target) {
    
    
        int i = 0, j = nums.length - 1;
        while (i < j){
    
    
            if(nums[i] + nums[j] == target){
    
    
                int[] ans = new int[]{
    
    nums[i],nums[j]};
                return ans;
            }
            else if((nums[i] + nums[j]) > target){
    
    
                j--;
            }else
            {
    
    
                i++;
            }
        }
        return null;
    }

    public static void main(String[] args) {
    
    
        jianzhi_Offer_57 obj = new jianzhi_Offer_57();
        int[] nums = new int[]{
    
    15,31,40,43,55,55,56,56,82,98};
        int[] ans = obj.twoSum1(nums, 111);
        for (int i: ans
             ) {
    
    
            System.out.println(i);
        }
    }
}

Supongo que te gusta

Origin blog.csdn.net/Puppet__/article/details/115127782
Recomendado
Clasificación