blog

JSアルゴリズム学習の旅 - 配列

17.電話番号のアルファベット順の組み合わせ 2~9の数字だけを含む文字列が与えられたとき、その文字列が表すことのできるすべての文字の組み合わせを返します。 数字と文字の対応付けは以下のようになります...

May 27, 2020 · 4 min. read
シェア

電話番号のアルファベット順の組み合わせ

2-9の数字のみを含む文字列が与えられた場合、その文字列が表すことのできるすべての文字の組み合わせを返します。

数字と文字の対応付けは以下の通り。1はどの文字にも対応していないことに注意してください。

入力: "23" 出力: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].注意:上記の答えは辞書順ですが、答えを出力する順番は自由に選ぶことができます。

出典:フォースボタン リンク

アイデア:入力された数字を2つずつ対応する文字にマッピングします。

方法1:

function combination(str) {
 //電話番号キーパッドのマッピング
 let mapArr = ['', 1, 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz'];
 //入力文字列を配列 "23 "に分割する=>[2,3]
 let num = str.split('');
 //入力のマッピングを保持する空の配列を定義する 例23=> [abc,def]
 let code = [];
 num.forEach(item => {
 if (mapArr[item]) {
 code.push(mapArr[item]);
 }
 })
 //組み合わせ関数
 let comb = (arr) => {
 let temporary = [];
 //外側のループは最初の要素の内容を走査し、外側のループは2番目の要素の内容を走査する
 for (let i = 0; i < arr[0].length; i++) {
 for (let j = 0; j < arr[1].length; j++) {
 temporary.push(`${arr[0][i]}${arr[1][j]}`);
 }
 }
 arr.splice(0, 2, temporary);
 //2つ以上の要素が組合せ関数を再帰的に呼び出している
 if (arr.length > 1) {
 comb(arr);
 } else {
 return temporary;
 }
 return arr[0];
 }
 return comb(code);
}

関与する知識ポイント。

2, Array.prototype.splice()

再帰

カードのグループ化

一組の山札があり、それぞれの山札には整数が書かれています。

この時点で、以下のルールに従ってデックを1つ以上のグループに分けることができるように、数字Xを選択する必要があります:

各グループには X 枚のカードがあります.グループ内のすべてのカードには同じ整数が書かれています。オプションの X >= 2 の場合のみ真を返します。

例1:

入力 : [1,2,3,4,4,3,2,1] 出力 : 真 解説 : 実現可能なグループ分けは [1,1], [2,2], [3,3], [4,4] です。

例 2:

入力:[1,1,1,2,2,2,3,3] 出力:偽 説明:要件を満たすグループ分けはありません。

例3:

Input : [1] Output : false Explanation : 要件を満たすグルーピングはありません。

例4:

入力 : [1,1] 出力 : true 解説 : 実現可能なグループ分けは [1,1] です。

例5:

入力 : [1,1,2,2,2,2] 出力 : 真 解説 : 実現可能なグループ分けは [1,1], [2,2], [2,2] です。

ヒント

1 <= deck.length <= 10000 0 <= deck[i] < 00100

出典:フォースボタン リンク

アイデア:例1を通じて、まずソートするために知っている、例2を通じて、5が偽を返すために誓約1の最小限の数の異なる番号の数を見つけるために知っている、誓約1の最小限の数の例2は、グループ化の例3は、偽を返すように要件を満たすために望んでいませんでした。

let hasGroupsSizeX = function (arr) {
 //ソートしてから文字列に変換し、正規マッチングを行う
 let str = arr.sort().join('');
 // 2つの数の最大公約数を求める
 let gcd = function (a, b) {
 if (a % b === 0) return b;
 return gcd(b, a % b);
 }
 //  
 let group = str.match(/(\d)\1+|\d/g);
 // グループ内の最初の2つの要素を別々に取り除き、これら2つの要素の長さの最小公倍数を求める。
 //最小公倍数が1より大きい場合、「最小公倍数」を追加する。”同じ文字をグループ化し、グループ化された要素が1つになるまで、グループ化された次の要素との最小公倍数を求める。
 while (group.length > 1) {
 let a = group.shift().length;
 let b = group.shift().length;
 let v = gcd(a, b);
 if (v === 1) {
 return false;
 } else {
 group.unshift('0'.repeat(v));
 }
 }
 return group.length ? group[0].length > 1 : false;
}

関与する知識ポイント。

配列.prototype.splice()

3, String.prototype.match()

4.Array.prototype.shift()

配列.prototype.unshift()

6, String.prototype.repeat()

花植え問題

とても長い花壇があり、その区画の一部には花が植えられていて、もう一部には植えられていないとします。しかし、隣の区画に花を植えることはできません。

花壇があり、n個の花が植えられているとします。n 個の花を植えることができますか?可能なら真を、不可能なら偽を返します。

例1.

入力: flowerbed = [1,0,0,0,1], n = 1 出力: 真 例2.

入力:flowerbed = [1,0,0,0,1], n = 2 出力:False 以下のことに注意してください。

配列内にすでに植えられている花は、植え付けルールに違反しません。入力配列の長さは [1, 20000] の範囲です。n は非負の整数で、入力配列のサイズを超えることはありません。

出典:フォースボタン リンク

アイデア:1.データモデリング。 2.境界問題、最初と最後が0の場合。 3.1つの要素だけが0にカットされる場合。

/**
 * @param {number[]} flowerbed
 * @param {number} n
 * @return {boolean}
 */
let canPlaceFlowers = (flowerbed, n) => {
 let count = 0;
 for(let i=0; i<flowerbed.length; i++){
 if(flowerbed[i] == 0){
 if(i == 0 && (flowerbed[1] == 0 || flowerbed.length == 1)){
 count++;
 i++;
 }else if(i == flowerbed.length - 1 && 
 flowerbed[i] == 0 && 
 flowerbed[i - 1] == 0){
 count++;
 }else if(flowerbed[i - 1] == 0 && flowerbed[i + 1] == 0){
 count++;
 i++;
 }
 }
 }
 return count >= n;
};
Read next

GitLab CI + Docker 継続的インテグレーションマニュアル

伝統的なソフトウェア開発では、コードの統合は通常、全員が作業を終えた後にプロジェクトの終了間際に行われ、多くの時間と労力がかかります。継続的インテグレーションとは、コードのビルド、テスト、統合をより定期的に行うために、統合フェーズをソフトウェア開発フェーズに置くことです。 「継続的インテグレーションはバグをなくすのではなく、バグを見つけやすくし、修正しやすくするものです。 継続的インテグレーション...

May 27, 2020 · 4 min read