[失業者のフロントエンド悪補足アルゴリズム]JavaScript leetcode トップ100 (6): アナグラムのグループ化、最長連続シーケンス、文字列内のすべてのアナグラムの検索、最大の部分配列の合計、およびそれ自体以外の配列の積

コラムステートメント: 最も単純でわかりやすい方法で合格するだけです。最適化は求めません。気に入らない場合はスプレーしないでください。

49. アナグラムのグループ化

タイトル

文字列の配列が与えられた場合、アナグラムを結合してください。結果のリストは任意の順序で返すことができます。

アナグラムは、原語のすべての文字を並べ替えることによって得られる新しい単語です。

知識ポイント:

ハッシュテーブル、ソート

一連の考え

ここでは js 言語のちょっとしたトリックが使用されています。分割 API を使用して文字列を文字の配列に変換し、得られた配列をソートして、アナグラムが結果の文字列の一貫性を取得できるようにします。ハッシュ テーブルには、出力された 2 桁の配列内の結果文字列に対応する配列の添字が保存され、この添字に従って各文字列が挿入される位置を見つけることができます。

コード
/**
 * @param {string[]} strs
 * @return {string[][]}
 */
var groupAnagrams = function (strs) {
    
    
    var obj = {
    
    

    };
    let re = [];

    for (var i = 0; i < strs.length; i++) {
    
    

        let key = strs[i].split('').sort().join('');
        if (typeof obj[key] == 'undefined') {
    
    
            re.push([strs[i]]);
            obj[key] = re.length - 1;
        } else {
    
    
            re[obj[key]].push(strs[i]);
        }
    }
    return re;
};

128. 最長連続シーケンス

タイトル

ソートされていない整数配列 nums を指定して、連続する数値の最長シーケンスの長さを見つけます (シーケンスの要素が元の配列で連続している必要はありません)。
この問題を解決するには、時間計算量 O(n) のアルゴリズムを設計して実装してください。

知識ポイント:

ハッシュテーブル、セット

一連の考え

2 回走査します。最初にデータがセットに格納されるとき、目的は重複要素を削除し、その後セットを走査します。現在の要素 -1 の要素が配列内にない場合、現在の要素が配列内にないことを意味します。シーケンスの左端の要素を開始点として使用し、次のビット位置が見つからなくなるまで順番に増加するシーケンスを前方検索し、その長さを記録し、最長の長さを出力します。

コード
/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function (nums) {
    
    
    let num_set = new Set();

    for (var i = 0; i < nums.length; i++) {
    
    
        num_set.add(nums[i]);
    }

    let re = 0;

    for (const num of num_set) {
    
    

        if (!num_set.has(num - 1)) {
    
    
            let s = 0;
            while (num_set.has(num + s)) {
    
    
                s++;
            }
            re = Math.max(re, s);
        }
    }
    return re;
};

438. 文字列内のすべてのアナグラムを検索する

タイトル

2 つの文字列 s と p を指定すると、s 内の p のすべてのアナグラム部分文字列を検索し、これらの部分文字列の開始インデックスを返します。回答が出力される順序は考慮されません。

アナグラムとは、同じ文字を並べ替えた文字列(同じ文字列を含む)を指します。

知識ポイント:

ハッシュテーブル、スライディングウィンドウ

一連の考え

まず 26 ビットのハッシュ テーブルを開いて各文字の出現回数を保存し、次にターゲット文字列 p をハッシュします。

このトリックは js 言語を使用します。配列に対して toString メソッドを使用すると、分割された各配列要素で構成される文字列が返されます,。次に、2 つのハッシュ テーブルに対して toString メソッドを使用すると、それらが同じであれば、取得された文字列も同じなので、このメソッドを使用してアナグラムをすばやく判断できます

その後、s 文字列に対してスライディング ウィンドウ操作を実行し、p と同じサイズの最初の領域を選択し、その中の各文字をハッシュ テーブルに処理します。この時点でハッシュ テーブルと p ハッシュの結果が同じであれば、次に、この添字を記録します。次に、1 ビット後方に移動し、ハッシュ テーブル内の最後のラウンド結果の最初の文字を削除し、次の新しい文字を追加します。次に、文字列全体が走査されるまで等価比較を実行します。出力 結果は次のようになります。

コード
/**
 * @param {string} s
 * @param {string} p
 * @return {number[]}
 */
var findAnagrams = function (s, p) {
    
    

    let h1 = new Array(26).fill(0);
    let h2 = new Array(26).fill(0);

    for (var i = 0; i < p.length; i++) {
    
    
        h2[p.charCodeAt(i) - "a".charCodeAt(0)]++;
    }
    let now = 0;
    let re = [];
    for (var i = 0; i < s.length; i++) {
    
    
        h1[s.charCodeAt(i) - "a".charCodeAt(0)]++;
        now++;
        if(now == p.length){
    
    
            if(h1.toString() == h2.toString()){
    
    
                re.push(i - p.length + 1);
            }
            h1[s.charCodeAt(i - p.length + 1) - "a".charCodeAt(0)]--;
            now--;
        }  
    }
    return re;
};

53. 最大サブアレイ合計

タイトル

整数の配列 nums を指定して、最大の合計を持つ連続部分配列 (部分配列には少なくとも 1 つの要素が含まれます) を見つけて、その最大の合計を返します。サブアレイ。配列の連続した部分です。

知識ポイント:

動的プログラミング

一連の考え

動的プログラミングの典型的な質問: 各ビットについて、前のビットの連続する部分配列の最大合計が負の場合、それを加算した方が加算しないよりも小さくなければならないため、現在のビットから直接部分配列を再計算すると、最適解、そうでない場合は、前のビットの連続サブ配列の最大合計に現在のビットを加えたものです。現在のビットの連続サブ配列の最大合計です。この考え方に従って各ビットを順番に処理し、毎回表示される最大値を更新して、最終的に次のように出力します。

コード
/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function (nums) {
    
    
    var dp = [];
    dp[0] = 0;
    let re = -10000;
    for (var i = 1; i <= nums.length; i++) {
    
    
        dp[i] = Math.max(dp[i-1],0)+nums[i-1];
        re = Math.max(re,dp[i]);
    }
    return re;
};

238. それ自体以外の配列の積

タイトル

整数配列 nums を指定すると、配列の Answer を返します。answer[i] は、nums[i] を除く nums のすべての要素の積に等しくなります。

タイトル データは、配列 nums 内のすべてのプレフィックス要素と任意の要素のサフィックスの積が 32 ビット整数の範囲内であることを保証します。

除算を使用せず、この問題を O(n) 時間の計算量で解決してください。

知識ポイント:

プレフィックスと

一連の考え

従来のプレフィックスとタイトルの場合、前処理に head と back の 2 つの配列を使用します。

  • head は添字 0 から i -1 までの数値を乗算した積を表します。
  • back は、添字の最後の桁から i + 1 までの数値を順番に乗算した積を表します
    。この場合、end 配列の i 番目の桁は back[i] * head[i] の末尾となり、出力は順次処理できる
コード
/**
 * @param {number[]} nums
 * @return {number[]}
 */
var productExceptSelf = function (nums) {
    
    

    let head = new Array(nums.length).fill(1);
    let back = new Array(nums.length).fill(1);

    for (var i = 1; i < nums.length; i++) {
    
    
        head[i] = head[i - 1] * nums[i - 1];
    }
    for (var i = nums.length - 2; i >= 0; i--) {
    
    
        back[i] = back[i + 1] * nums[i + 1];
    }
    for (var i = 0; i < nums.length; i++) {
    
    

        nums[i] = back[i] * head[i];
    }
    return nums;
};

おすすめ

転載: blog.csdn.net/weixin_46463785/article/details/131464249