コンテンツ
1.欲張りアルゴリズムの概要
基本的な考え方
1)欲張りアルゴリズム(欲張りアルゴリズム)とは、問題を解決するときに、選択の各ステップで最良または最適な(つまり、最も好ましい)選択を行い、最良または最適なアルゴリズムにつながることを期待することを指します。
2)欲張りアルゴリズムによって得られた結果は、必ずしも最適な結果ではありません(場合によっては最適なソリューションになります)が、最適なソリューションに比較的近い(近い)結果です。
制限
欲張りアルゴリズムが失敗する大きな理由は、その明らかな制限です。ほとんどの場合、局所最適点のみが考慮されます。いわゆるローカル最適化は、現在の最善の利益のみを考慮し、一歩前進も後退もしないため、毎回現在の段階の最適解のみが使用されます。したがって、ほとんどの場合、欲張りアルゴリズムは全体的な最適解を取得できませんが、その解は最適解の適切な近似です。
2.古典的な例
間隔の問題
複数の間隔が与えられた場合、それらが重複しないようにするために削除する間隔の最小数を計算します。開始接続と終了接続は重複としてカウントされません。
入出力例
入力は、間隔の開始と終了を表す2の固定長を持つ複数の配列で構成される配列です。
削除する間隔の数を表す整数を出力します。
入力:[1,2]、[2,4]、[1,3]]
出力:1
この例では、残りの間隔[1,2]、[2,4]]が互いに重ならないように、間隔[1,3]を削除できます。
欲張り戦略
保持する間隔を選択するときは、間隔の終わりが重要です。選択する間隔の終わりが小さいほど、他の間隔のために残されたスペースが多く
なり、保持できる間隔が多くなります。
したがって、私たちが採用する貪欲な戦略は、小さな終わりと互いに素な間隔で間隔を優先的に維持することです。具体的な実装方法は次のとおりです。
1.最初に、端のサイズに従って間隔を昇順で並べ替えます。
2.毎回、終了が最小で、前に選択した間隔と重ならない間隔を選択します。
この例では、ソートされた配列は[1,2]、[1,3]、[2,4]]です。欲張り戦略に従って、最初に間隔[1,2]に初期化します。[1,3]は[1,2]と交差するため、この間隔をスキップします。[2,4]は[1、 2]、それを保持します。したがって、最終的な予約間隔は[1,2]、[2,4]です。
3.コード
import java.util.Arrays;
import java.util.Comparator;
public class Solution {
public static int merge(int[][] intervals) {
//先按照区间结尾的大小进行升序排序
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
int count =1;//区间不重合的个数,默认第一个满足题意,初始化为1
int cur = intervals[0][1];//排序完成后贪心选择的最小的区间结尾
for (int i = 1; i < intervals.length; i++) {
if(intervals[i][0] >= cur) {
count++;
cur=intervals[i][1];
}
}
//所有区间的个数减去不重叠区间的个数,就是重叠区间的个数。
return intervals.length - count;
}
}