LeetCode1024. Unión de video (Java + codicioso)

Obtendrá una serie de videoclips de un evento deportivo que durará T segundos. Estos fragmentos pueden superponerse o pueden variar en longitud. Los clips de vídeo [i] están representados por intervalos: comienzan en los clips [i] [0] y terminan en los clips [i] [1]. Incluso podemos editar estos segmentos libremente, por ejemplo, el segmento [0, 7] se puede cortar en tres partes [0, 1] + [1, 3] + [3, 7].
Necesitamos volver a editar estos segmentos y unir el contenido editado en segmentos ([0, T]) que cubren todo el proceso de movimiento. Devuelve el número mínimo de fragmentos requeridos, o -1 si la tarea no se puede completar.

Ejemplo 1: Entrada: clips = [[0,2], [4,6], [8,10], [1,9], [1,5], [5,9]], T = 10
Salida: 3
Explicación: Seleccionamos los tres fragmentos [0,2], [8,10], [1,9]. Luego, rehaga el segmento del juego de acuerdo con el siguiente esquema: Edite [1,9] nuevamente a [1,2] + [2,8] + [8,9]. Ahora tenemos [0,2] + [2,8] + [8,10], y estos cubren todo el juego [0, 10].
Ejemplo 2:
Entrada: clips = [[0,1], [1,2]], T = 5
Salida: -1
Explicación: No podemos simplemente sobrescribir [0,5 con [0,1] y [1,2] ] Todo el proceso.
Ejemplo 3:
Entrada: clips = [[0,1], [6,8], [0,2], [5,6], [0,4], [0,3], [6,7], [1,3], [4,7], [1,4], [2,5], [2,6], [3,4], [4,5], [5,7], [6 , 9]], T = 9
Salida: 3
Explicación: Seleccionamos los segmentos [0,4], [4,7] y [6,9].
Ejemplo 4:
Entrada: clips = [[0,4], [2,8]], T = 5
Salida: 2
Explicación: Tenga en cuenta que puede grabar un video después del final del juego.

Análisis de temas

El requisito del título es encontrar los fragmentos mínimos que puedan cubrir T (no me ocupé de la "reedición" como decía el título, así que no creo que sea necesario).
Podemos ordenar la matriz unidimensional en la matriz bidimensional, y [i] [0] Organizar de menor a mayor, si es el mismo [i] [0], organizar [i] [1] de mayor a menor.

public int videoStitching(int[][] clips, int T) {
    
    
		// 我先排一个序,clipse[i][0]按从小到大排列,相同[i][0]则将[i][1]从大到小排列
		for (int i = 0; i < clips.length; i++) {
    
    
			Arrays.sort(clips, new Comparator<int[]>() {
    
    
				@Override
				public int compare(int[] o1, int[] o2) {
    
    
					if (o1[0] == o2[0]) {
    
    
						return o2[1] - o1[1];
					}
					return o1[0] - o2[0];
				}
			});
			;
		}
		for (int i = 0; i < clips.length; i++) {
    
    
		System.out.println(Arrays.toString(clips[i]));
	}

Después de ordenar la suma, establecemos dos punteros, izquierda y derecha, la izquierda apunta a los clips [i] [0], la derecha apunta a los clips [i] [1].
Recorre toda la matriz, en el caso de right <T, vamos a encontrar

clips [j] [0]> = izquierda && clips [j] [0] <= derecha && clips [j] [1]> derecha

Y actualizar bien.
Pero todavía no lo he considerado de manera exhaustiva. Tengo que considerar cómo calcular cuántos fragmentos.
Aquí subiré directamente el código, según el análisis de código.

public int videoStitching(int[][] clips, int T) {
    
    
		// 我先排一个序,clipse[i][0]按从小到大排列,[i][1]从大到小排列
		for (int i = 0; i < clips.length; i++) {
    
    
			Arrays.sort(clips, new Comparator<int[]>() {
    
    
				@Override
				public int compare(int[] o1, int[] o2) {
    
    
					if (o1[0] == o2[0]) {
    
    
						return o2[1] - o1[1];
					}
					return o1[0] - o2[0];
				}
			});
			;
		}
		for (int i = 0; i < clips.length; i++) {
    
    
		System.out.println(Arrays.toString(clips[i]));
	}
		//贪心算法
		//left指向clips[i][0],right指向clips[i][1],cnt计算多少片段
		//这道题的思路:如果clips[i][1]>right且right<T,说明这个数组在T范围内,更新right
		//找下一个clips[i][1]>right且right<T的数组
		int left = 0, right = 0, cnt = 0;
		for (int i = 0; i < clips.length && right < T; i++) {
    
    
			int tempRight = right, add = 0, j = i;
			//right<clips[i][0]的情况,说明后面的区间的起点>right,就发生断裂,视频接不上了
			if (right < clips[i][0]) {
    
    
				break;
			}
			for (j = i; j < clips.length && clips[j][0] <= right; j++) {
    
    
				if (clips[j][0] >= left && clips[j][0] <= right && clips[j][1] > right) {
    
    
					// 0>=0&&0<=0&&2>0
					tempRight = Math.max(clips[j][1], tempRight);
					add = 1;
				}
			}
			cnt += add;
			right = tempRight;
			i = j - 1;
		}
		if (right >= T) {
    
    
			return cnt;
		}
		return -1;

	}

Reflexión

Esta pregunta toma muchos detalles en consideración, y es difícil considerarla de manera tan completa. La pregunta es realmente tomarla con calma. Estoy mejorando constantemente y la dificultad de la pregunta también está aumentando. ¡Necesito más reflexión y revisión!
fin.

Supongo que te gusta

Origin blog.csdn.net/weixin_44998686/article/details/109269883
Recomendado
Clasificación