[リコウブラシの質問 | 17日目]

目次

序文:

55. ジャンプゲーム - LeetCode

45. ジャンプゲーム II - LeetCode

要約:


序文:

        現在、どちらのタイプも貪欲なアルゴリズムなので、何かを得ることができれば幸いです

55. ジャンプゲーム - LeetCode

負でない整数の配列を指定すると nums 、最初は 配列の最初のインデックスに位置します 。

配列内の各要素は、その位置でジャンプできる最大長を表します。

最後の添え字に到達できるかどうかを判断します。

実際、この質問は思考に焦点を当てており、多くの人がこの質問を貪欲なアルゴリズムのアイデアだと考えていますが、全員が思考の罠にはまっています。

最終的に目的地に到達できるように、現在の場所で次のステップを選択するにはどうすればよいですか。

しかし、このように考えると、欲張ってステップ数が多すぎて目的地に到達できない場合があるため、次のステップをどのように選択するかという難しい問題解決の考え方に陥ってしまいます。

したがって、行き方について心配するのではなく、カバレッジを見てみましょう. 例を挙げて説明します。

 カバレッジを水平線で表すことができます。

 3 が 4 をカバーしていることがはっきりとわかり、この配列では最後の点に移動できることがわかります。

別の反例を見てみましょう。

 この配列の要素 (最後の要素を除く) では最後の点をカバーできないことがわかり、どのように進んでも最後の点に到達することは不可能です。

したがって、この考えに基づいて、この質問に対する解決策を書くことができます。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int size =nums.size();
        int cover=0;
        for(int i=0;i<=cover;i++)
        {
           cover=max(nums[i]+i,cover);
            if(cover>=size-1)
            {
                return true;
            }         
        }
        return false;
    }
};

45. ジャンプゲーム II - LeetCode

ゼロから始まる長さ n の整数配列 nums を指定します。初期位置は nums[0] です。

各要素 nums[i] は、インデックス i から前方にジャンプする最大長を表します。言い換えると、nums[i] にいる場合は、任意の nums[i + j] にジャンプできます。

0 <= j <= nums[i] 
i + j < n は、
nums[n - 1] に到達するための最小ホップ数を返します。生成されるテスト ケースは nums[n - 1] に達する可能性があります。

 この質問も貪欲なアルゴリズムのアイデアですが、貪欲であるという間違った目的を持っている人が多いです 前の質問でカバレッジについて紹介しましたが、実際には、最小ジャンプ数を前提として、貪欲にするのはステップ数の多さではなく、カバレッジの最大値です

この問題解決のアイデアによれば、次のように結論付けることができます。

class Solution {
public:
    int jump(vector<int>& nums) {
        int size =nums.size();
        int cur=0;
        int next=0;
        int count=0;
        if(size==1)
        {
            return 0;
        }

        for(int i=0;i<size;i++)
        {
            next=max(i+nums[i],next);
            if(i==cur)
            {
                if(cur!=size-1)
                {
                    count++;
                    cur=next;
                }
                if(cur>=size-1)
                {
                    break;
                }
            }
        }
        return count;
    }
    
};

詳細に説明します。まず 4 つの変数を作成します。size は目的のポイントに到達するために必要な長さを示し、cur は現在のポイントのカバレッジを示し、next はこれからジャンプしようとしているポイントのカバレッジを示し、count はジャンプの数を記録します。

その後、現在の場所のカバレッジに基づいて、次に大きいカバレッジを遡って調べます。これは、for ステートメント内の 3 つの if の関数です。

  • if(i==cur) は、現在のカバレッジ内で次の最大カバレッジを判断したかどうかを判断するために使用されます。
  • if(cur!=size-1) は、現在のカバーエリアが目的のポイントをカバーしていないかどうかを判断するために使用されます。カバーされていない場合は、カバーされていないことを意味します。カバーされていない場合は、次に大きいカバー ポイント (cur=next) に移動し、ジャンプ数 +1 (count++) を与えます。
  • if(cur>=size-1) は、現在のカバーエリアが目的点をカバーしているかどうかを判断するために使用され、カバーされている場合は、この時点のジャンプステップ数がすでに最短ジャンプステップ数であることを意味し、ループを直接抜けて結果を出力します。

要約:

貪欲アルゴリズムのテーマは常に変化しており、私たちはまだ多くの質問を通じて貪欲アルゴリズムのアイデアをさらに習得する必要があります。

私のコンテンツがお役に立ちましたら、「いいね!」、コメント、ブックマークをお願いします。創作は簡単ではありませんが、皆さんのサポートが私の頑張りの原動力です!

 

 

おすすめ

転載: blog.csdn.net/fckbb/article/details/131688674