LeetCode.1046-最後の石の重量(最終ストーン重量)

これは、最初の小川である388、最初の更新418ピアン原稿

01の質問と準備ができて見えます

今日導入されLeetCodeのタイトルにアルゴリズムやすいのレベル250の(全体のタイトル番号がある質問1046)。石のセットは、それぞれの石は、重量で、正の整数値を有します。

たびに、私たちは最も重要な岩のうちの2つを選択し、それらを一緒に粉砕しています。石及びX Y、X <= Yの重量を想定。砕石結果:

  • x == yの場合、二つの石が完全に粉砕されています。

  • X!= Y場合は、xは石の重量がy YXの新しい重みを持つ石の重量として、完全に潰されています。

最後に、石までの残りの部分。戻る重量石(何の石が残っていない場合は、0を返します)。

例えば:

入力:[2,7,4,1,8,1]
出力:1つの
説明:
我々 7,8が1を与えるために結合される、アレイは、[2,4,1,1,1]に変換され
、その後、我々は、意志2図2及び図4に示すように与えるために結合されるので、アレイは[2,1,1,1]に変換され、
そして1および2は1を与えるために結合される、アレイは[1,1,1]に変換され
、その後、我々は1になり、1 0を与えるために組み合わせるので、アレイは、最後の石の[1]、即ち、重量値に変換されます。

注意

  • 1 <= stones.length <= 30

  • 1 <=石[I] <= 1000

02第一溶液

タイトルの意味によると、私たちは大きな値を入れていない、2つの数の最大の配列、まず、2つのことを行うために、全体殺すに等しい値の交換、サイズを見つけるために、それぞれの時間を必要とするの両方を交換してください等しくキルより小さい差、第二、第一のステップは、すべての要素が殺され、または最後の要素でなければならないまで繰り返されます。

アイデア:最初のアレイがソートされ、素子の数についての統計があるため、0であるstones[i]範囲[1 1000]、(0で置き換え)交換サイクル値、アレイ内の要素の数最後の値が0に等しくなるまでstones.length、またはstones.length-1サイクルの終了前に。配列の最後の要素が0に等しくない場合は、この要素の値が返され、そうでなければ0を返します。

public int lastStoneWeight(int[] stones) {
    int n = stones.length;
    while (!(checkStones(stones) == n || checkStones(stones) == n-1)) {
        if (stones[n-2] == stones[n-1]) {
            stones[n-2] = 0;
            stones[n-1] = 0;
        } else {
            stones[n-1] -= stones[n-2];
            stones[n-2] = 0;
        }
    }
    // 全是0,或者只有最后一个元素不为0
    return stones[n-1] == 0 ? 0 : stones[n-1];
}

/**
 * 统计数组stones中值为0的元素个数
 * @param stones
 * @return
 */
public int checkStones(int[] stones) {
    Arrays.sort(stones);
    int count = 0, n = stones.length;
    for (int i=0; i<n; i++) {
        if (stones[i] == 0) {
            count++;
        }
    }
    return count;
}


03第二の溶液

我々はさらに、第一溶液を簡素化することができます数をカウントしていない、まだ交換0件名、同じ効果の規則に従ってください。

public int lastStoneWeight2(int[] stones) {
    int n = stones.length;
    for (int i=0; i<n-1; i++) {
        Arrays.sort(stones);
        if (stones[n-2] == stones[n-1]) {
            stones[n-2] = 0;
            stones[n-1] = 0;
        } else {
            stones[n-1] -= stones[n-2];
            stones[n-2] = 0;
        }
    }
    // 全是0,或者只有最后一个元素不为0
    return stones[n-1] == 0 ? 0 : stones[n-1];
}


04第三の溶液

各サイクルにおける第一溶液と第二溶液に再ソートアレイに必要、この工程を省略することができますか?

答えはイエス、使用されたプライオリティキューが実装されています。

初期化優先度キューに、そこに選択されるComparatorコンストラクタ引数、その選択としてreverseOrder、その後の処理サイクルを開始し、方法、逆の順(降順)、キューに配列の要素。プライオリティキューは、2つの差が0より大きい場合の両方が、除去減算、第二の大きな値に続くキューの最大頭、常に、自動的にソートされているので、差がキューであろう。最後に、キューが空、空の戻り0、最初のチームのない空の戻り要素の値であるかどうかを判断します。

public int lastStoneWeight3(int[] stones) {
    PriorityQueue<Integer> pq = new 
            PriorityQueue<>(Comparator.reverseOrder());
    for (int stone : stones) {
        pq.offer(stone);
    }
    while (pq.size() > 1) {
        int num = pq.poll() - pq.poll();
        if (num > 0) {
            pq.offer(num);
        }
    }
    return pq.isEmpty() ? 0 : pq.peek();
}


05まとめ

テーマ別のアルゴリズムは、継続的にされている日以上7ヶ月、特集記事のアルゴリズム256件の +記事、公衆番号]ダイアログボックスの返信[ データ構造とアルゴリズム ]、[ アルゴリズム ]、[ データ構造 ]のいずれかの記事のコレクションのシリーズを取得するキーワード。

それは、すべてだあなたは何か良い解決策のアイデア、提案やその他の問題がある場合、あなたは以下のコメントを交換することができ、親指、メッセージ転送およびサポートは、私にとっての最大の報酬です!

おすすめ

転載: www.cnblogs.com/xiaochuan94/p/11220562.html