Búsqueda binaria para encontrar K elementos más cercanos de una matriz

Estoy aprendiendo la búsqueda binaria en leetcode del problema Find K Closest Elements - LeetCode

Dada una matriz ordenada, dos enteros ky x, encontrar los kelementos más cercanos a xla matriz. El resultado también debe clasificarse en orden ascendente. Si hay un empate, siempre se prefieren los elementos más pequeños.

Ejemplo 1:

Input: [1,2,3,4,5], k=4, x=3
Output: [1,2,3,4]

Ejemplo 2

Input: [1,2,3,4,5], k=4, x=-1
Output: [1,2,3,4]

Nota:

  1. El valor k es positivo y siempre será menor que la longitud de la matriz ordenada.
  2. La longitud de la matriz dada es positiva y no excederá de 104
  3. El valor absoluto de los elementos en la matriz yx no excederá de 104

Es la solución oficial:

Enfoque 2: Búsqueda binaria y dos punteros

Algoritmo

La matriz original se ha ordenado para que podamos aprovechar esta ventaja con los siguientes pasos.

  1. Si el objetivo xes menor o igual que el primer elemento en la matriz ordenada, los primeros kelementos son el resultado.

  2. Del mismo modo, si el objetivo xes más o igual que el último elemento en la matriz ordenada, los últimos kelementos son el resultado.

  3. De lo contrario, podemos usar la búsqueda binaria para encontrar el indexelemento, que es igual (cuando esta lista tiene x) o un poco más grande que x(cuando esta lista no lo tiene). Luego, colóquelo lowen su k-1posición izquierda y highen la k-1posición derecha de esto indexcomo inicio. Los números k deseados deben estar en este rango [index-k-1, index + k-1]. Entonces podemos reducir este rango para obtener el resultado usando las siguientes reglas.

    • Si lowalcanza el índice más bajo 0o el lowelemento está más cerca xque el highelemento, disminuya el highíndice.

    • Si highalcanza el índice más alto arr.size()-1o está más cerca xque el lowelemento, aumente el lowíndice.

    • El bucle termina cuando hay exactamente k elementos en [bajo, alto], cuya sublista es el resultado.

La implementación

public class Solution {
    public List<Integer> findClosestElements(List<Integer> arr, int k, int x) {
        int n = arr.size();
        if (x <= arr.get(0)) {
            return arr.subList(0, k);
        } else if (arr.get(n - 1) <= x) {
            return arr.subList(n - k, n);
        } else {
            int index = Collections.binarySearch(arr, x);
            if (index < 0)
                index = -index - 1;
            int low = Math.max(0, index - k - 1), high = Math.min(arr.size() - 1, index + k - 1); #1????

            while (high - low > k - 1) {
                if (low < 0 || (x - arr.get(low)) <= (arr.get(high) - x)) #2????
                    high--;
                else if (high > arr.size() - 1 || (x - arr.get(low)) > (arr.get(high) - x)) #????
                    low++;
                else
                    System.out.println("unhandled case: " + low + " " + high);
            }
            return arr.subList(low, high + 1);
        }
    }
}

Tengo 3 preguntas sobre la implementación.

  1. low = Math.max(0, index - k - 1), Lo asumí como low = Math.max(0, index - k - 1), ya que la posición izquierda baja [index -k +1]no lo es [index-k-1].
  2. if (low < 0 || (x - arr.get(low)) <= (arr.get(high) - x)) #2????, Ya que bajo se fijó como low = Math.max(0, index - k - 1),y aumentará hacia delante, es necesario comprobar low < 0, el mismo queelse if (high > arr.size() - 1 || (x - arr.get(low)) > (arr.get(high) - x)) #????
  3. while (high - low > k - 1), ¿cuál es el beneficio de esto high - low >=k?
Respuesta 1

I have a Swing GUI running on WinXP. Sometimes, when i do something else (surf on the web...) and then i want to go back to my program, the GUI appears but is totally frozen, i can't do anything on ...

Estoy haciendo un proyecto de Android y tengo un archivo de formato .bin que lo puse justo en la raíz de mi proyecto de Java (no en ninguna carpeta). Traté de recuperarlo usando FileInputStream como a continuación: ...

En mi programa recibo tweets de Twitter para una consulta específica. Quiero calcular con qué frecuencia la gente twittea sobre este tema. Hasta ahora lo que hice es; Obtuve las fechas de dos tweets y encontré ...

Estoy usando JOOQ como una herramienta de creación de SQL para luego ejecutar en un jdbcTemplate. Necesito agregar dinámicamente uniones de tabla a la cláusula from. En este momento lo estoy haciendo así .. SeleccioneJoinStep <?> ...