アルゴリズムの詳細な説明: Yang Hui の三角形 | 2 つの順序付けされた配列をマージ | 順序付けされた配列内の重複を削除


前書き: 今回共有されたトピックはすべて Likou.com からのものであり、独自の課題を選択することができます。詳細なリンク:

118. ヤン・フイ・トライアングル – LeetCode

88. 2 つのソートされた配列をマージする - LeetCode

26. 順序付き配列内の重複を削除する - LeetCode

目次

1. ヤン・フイ・トライアングル

アイデア:

完全なコード:

2. 2 つの順序付けされた配列をマージする

アイデア:

完全なコード:

3. 順序付けされた配列内の重複を削除する

アイデア:

完全なコード:


1. ヤン・フイ・トライアングル

タイトル:負でない整数を指定すると numRows「ヤン・ホイの三角形」の最初の部分を生成します" a> numRows 行 (1 <= numRows <= 30)

注:「楊輝の三角形」では、各数字は左上と右上の数字の合計です

例 1:

输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

 例 2:

输入: numRows = 1
输出: [[1]]

アイデア:

ヤン・ホイの三角形の向きを変えて、はしご型に変更することもできますが、その方が理解に適しています。このようなはしご型のデータであれば、当然二次元配列を考えることになるでしょう。それで、ヤン・ホイの三角形を使用することはできますか? 2 次元配列として? 配列の実装についてはどうですか?

データの各行の最初と最後のデータは両方とも 1 で、残りのデータは前の行の同じ位置にあるデータと前のデータを加えたものになります。つまり、各行のデータを実装するときにこれを使用する必要があります。前の行のデータ。上記のプロセスをより効率的に完了するために、2 次元配列の代わりに 2 次元シーケンス テーブルを使用して操作できます。

2 次元のシーケンス テーブルを使用することに決めたら、外側の層for ループ<を使用して、各行に対応するシーケンス テーブルを格納する一般的なシーケンス テーブルを定義する必要があります。 /span> を使用して各行の要素を決定します。上記はこの質問の一般的な枠組みを決定します。 for ループ行数を決定し、 内部層

注意すべき詳細がいくつかあります。

Yang Hui の三角形の概要観察。すべての1 位置は各線の先頭と末尾にあり、先頭は非常に単純で、内層for ループ; は開始位置であり、最後の要素について、その座標を注意深く観察すると、その行数と列数が等しいことがわかります。これは、外側の j=0 for ループ i および内層for ループ変数 (j == 0 || j == i) “1” 、行シーケンス テーブルに要素を追加します は、要約すると、ループ変数 j

1 以外のデータの場合は、 を通じて前の行のデータにアクセスする必要があります。 get( i-1) は前の行の順序表を取得できます。前の行の順序表を取得した後、この行の j を取得します。 を使用して、この値をこの行のシーケンス テーブルに追加します。 .add 位置要素をそれぞれ追加し、それらを加算します。加算の結果は次のようになります。必要な値を入力し、最後に j-1 位置要素と

完全なコード:

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ret = new ArrayList<>();
        for (int i = 0; i < numRows; i++) {
            //新定义一行
            List<Integer> row = new ArrayList<>();
            for (int j = 0; j <= i; j++) {
                if (j == 0 || j == i) {
                    row.add(1);
                }else {
                    //添加上一行的数据(上一行的j-1和j位置)
                    row.add(ret.get(i-1).get(j-1) + ret.get(i-1).get(j));
                }
            }
            //每一次将新的一行加入总的二维顺序表中
            ret.add(row);
        }
        return ret;
    }
}

2. 2 つの順序付けされた配列をマージする

タイトル: 2 つの整数配列を 非減少順  < a i=4> と 、および 2 つの整数  と  はそれぞれ  です。  を  にマージして、マージされた配列も  降順に配置してください。  。 nums1 nums2mnnums1nums2 nums2 nums1

注:最終的に、結合された配列は関数によって返されるのではなく、配列 nums1 に格納される必要があります。この状況に対処するために、 nums1 の初期の長さは m + n です。ここで、最初の m 要素は、必要な要素を表します。最後の n 要素は 0 であるため、無視する必要があります。 nums2 の長さは n です。

例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] 

例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 

 例 3:

入力:nums1 = [0]、m = 0、nums2 = [1]、n = 1
出力: [1]
説明: マージする必要がある配列は [] と [1] です。 
結合した結果は [1] です。

アイデア:

配列の場合、それを新しい配列にマージする必要があります。2 つのポインターを使用して 2 つの配列をそれぞれ指し、2 つのポインターを小さい方の値と比較し、小さい方の値を新しい配列に代入します。ポインタが後方に移動する

データの挿入には合計 4 つの状況があり、それぞれに対処します。

  1. nums1 のデータは  nums2 のデータより小さいです: nums1 のデータを新しい配列に入れます、ポインタ pA が移動した後
  2. nums1 のデータは  nums2 のデータより大きいです: nums2 のデータを新しい配列に入れます、ポインタ pB 移動後
  3. nums1 のデータは除外されましたが、 nums2 にはまだ要素があります。 nums2 の要素を新しい配列に入れ、ポインタ pB を戻します。
  4.  nums2 のデータは削除されましたが、 nums1 にはまだ要素があります。 nums1 の要素を新しい配列に入れ、ポインタ pA を戻します。

while ループを使用してすべての状況トラバーサルを含め、各判断で一時的な配列を介してデータの一部を新しい配列に入れます。変数 、質問の要件を満たすために、最終結果は配列 1 に上書きされます

完全なコード:

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int pA = 0;
        int pB = 0;
        int cur = 0;
        int[] sordNum = new int[m + n];
        while (pA < m || pB < n) {
            if (pA == m) {//nums1已满,放入nums2
                cur = nums2[pB++];
            } else if (pB == n) {//nums2已满,放入nums1
                cur = nums1[pA++];
            } else if (nums1[pA] < nums2[pB]) {//nums1的数据小于nums2
                cur = nums1[pA++];
            } else {//nums1的数据大于等于nums2
                cur = nums2[pB++];
            }
            sordNum[pA + pB - 1] = cur;
        }
        for (int j = 0; j != m + n; ++j) {
            nums1[j] = sordNum[j];
        }
    }
}

3. 順序付けされた配列内の重複を削除する

タイトル: 配列を提供します 非厳密に増加する配置 nums 、各要素が 1 回だけ表示されるように、  繰り返し要素をその場で削除してください  。  の一意の要素の数を返します。  を保つ必要があります。次に、 一貫性 は 相対的な順序 は、削除後の配列の新しい長さを返します。要素の nums

例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]

例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]

アイデア:

ここでの削除については、これをうまく利用できます。具体的には、反復しない要素を前に置くことができます。配列を取得し、非繰り返し要素のこの部分のみを返すことで、偽装削除の目的を達成します

完全なコード:

class Solution {
    public int removeDuplicates(int[] nums) {
        //快慢指针
        int left = 0;
        int right = 1;
        while(right < nums.length){
            if(nums[left] != nums[right]){
                left++;
                nums[left] = nums[right];
            }
            right++;
        }
        return left + 1;
    }
}



  今回の共有は以上です。私の共有があなたのお役に立てれば幸いです。皆さんのサポートも歓迎します。あなたの「いいね!」は、ブロガーにとって更新する最大の動機です。 異なる意見がある場合は、コメント エリアで積極的に議論して交換してください。一緒に学び、進歩していきましょう。 関連する質問がある場合は、ブロガーにプライベート メッセージを送信することもできます。コメント エリアとプライベート メッセージは慎重にチェックされます。また次回お会いしましょう

おすすめ

転載: blog.csdn.net/m0_69519887/article/details/134805409