LeetCode1024。ビデオスティッチング(Java + greedy)

T秒間続くスポーツイベントから一連のビデオクリップを取得します。これらのフラグメントは重複する場合もあれば、長さが異なる場合もあります。ビデオクリップクリップ[i]はすべて間隔で表されます。クリップ[i] [0]で始まり、クリップ[i] [1]で終わります。これらのセグメントを自由に編集することもできます。たとえば、セグメント[0、7]は3つの部分[0、1] + [1、3] + [3、7]にカットできます。
これらのセグメントを再編集し、編集したコンテンツを移動プロセス全体をカバーするセグメント([0、T])にスプライスする必要があります。必要なフラグメントの最小数を返します。タスクを完了できない場合は-1を返します。

例1:入力:クリップ= [[0,2]、[4,6]、[8,10]、[1,9]、[1,5]、[5,9]]、T = 10
出力: 3
説明:3つのフラグメント[0,2]、[8,10]、[1,9]を選択します。次に、次のスキームに従ってゲームセグメントを再作成します。[1,9]を[1,2] + [2,8] + [8,9]に再度編集します。これで[0,2] + [2,8] + [8,10]になり、これらはゲーム全体[0、10]をカバーします。
例2:
入力:clips = [[0,1]、[1,2]]、T = 5
出力:-1
説明:[0,5を[0,1]と[1,2]で上書きすることはできません。 ]プロセス全体。
例3:
入力: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
出力:3
説明:セグメント[0,4]、[4,7]、および[6,9]を選択します。
例4:
入力:clips = [[0,4]、[2,8]]、T = 5
出力:2
説明:ゲームの終了を超えるビデオを録画できることに注意してください。

トピック分析

タイトルの要件は、Tをカバーできる最小限のフラグメントを見つけることです(タイトルが言ったように「再編集」を扱っていなかったので、必要ではないと思います)
。1次元配列を2次元配列に並べ替えることができます。[i] [0]最小から最大に配置します。同じ[i] [0]の場合は、[i] [1]を最大から最小に配置します。

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]));
	}

合計を並べ替えた後、2つのポインターを設定します。左と右、左のポイントはクリップ[i] [0]、右のポイントはクリップ[i] [1]です。
配列全体をトラバースします。right<Tの場合、次のように検索します。

クリップ[j] [0]> =左&&クリップ[j] [0] <=右&&クリップ[j] [1]>右

そして、正しく更新します。
しかし、まだ包括的に検討していません。フラグメントの数を計算する方法を検討する必要があります。
ここでは、コードを直接アップロードし、コードに従って分析します。

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;

	}

反射

この質問は多くの詳細を考慮に入れており、それを包括的に検討することは困難です。問題は本当にゆっくりとそれをとることです。私は絶えず改善しており、質問の難易度も増しています。もっと反省とレビューが必要です!
終わり。

おすすめ

転載: blog.csdn.net/weixin_44998686/article/details/109269883