最小の文字の出現頻度のLeetCode.1170-文字列比較(最小シャアの頻度で文字列を比較)

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

問題を見て、準備

今日導入されLeetCodeのタイトルにアルゴリズムやすいのレベル263の(全体のタイトル番号がある質問1170)。機能が非空の文字列Sで定義されf(s)、関数が計算しs、最小の文字の出現頻度を。例えば、s ="dcce"その後、f(s)= 2なぜなら最小の文字の、"c"2の周波数。

ここで、文字列の配列を所与querieswords整数の配列を返しanswer
それぞれがanswer[i]そのようであるが、そのf(queries[i]) < f(W)単語の数Wであるwordsワードで。

例えば:

入力:クエリ= [ "CBD"] 、言葉= [ "zaaaz"]
出力:[1]
説明:最初のクエリでは、我々はf("cbd")= 1f("zaaaz")= 3それゆえf("cbd")<f("zaaaz")

入力:クエリ= [ "BBB"、 "CC"]、言葉= [ "A"、 "AA"、 "AAA"、 "AAAA"]
出力:[1,2]
説明:最初のクエリでは、唯一f("bbb")<f("aaaa")そうanswer[0] = 1
第二にf("cc")<f("aaa")、クエリf("cc")<f("aaaa")そうanswer[1] = 2

注意

  • 1 <= queries.length<= 2000
  • 1 <= words.length<= 2000
  • 1 queries[i].length<= words[i].length <= 10
  • queries[i][j]words[i][j]英語の小文字の手紙。

最初のソリューション

タイトルの要件を意味しwords、より少ない現れる文字の最小数を見つけるqueries出現数の最小値、最終的には、文字列内の単語の数queriesとして長さがint返された配列を。

したがって、我々は直接、タイトルを翻訳して、ループの二つの層、外側のループを使用することができますqueries見つけるために、文字列queries[i]の最小の文字の出現回数を、そして横断words場合、出現の2つの文字の最小数を比較すると、単語にqueries比較的小さな、カウントするために、内側ループの後、カウント結果が追加されているanswerアレイ、及び最終的に戻ります。

public int[] numSmallerByFrequency(String[] queries, String[] words) {
    int len = queries.length, len2 = words.length;
    int[] result = new int[len];
    for (int i=0; i<len; i++) {
        int query = minFrequency(queries[i]);
        int count = 0;
        for (int j=0; j<len2; j++) {
            int word = minFrequency(words[j]);
            if (query < word) {
                count++;
            }
        }
        result[i] = count;
    }
    return result;
}

/**
 * 找到字符串中的最小字符的出现次数
 * @param s
 * @return
 */
public int minFrequency(String s) {
    int[] arr = new int[26];
    int count = 0;
    for (int i=0; i<s.length(); i++) {
        arr[s.charAt(i)-'a']++;
    }
    for (int j=0; j<26; j++) {
        if (arr[j] != 0) {
            count = arr[j];
            break;
        }
    }
    return count;
}


第二の溶液

最初のソリューションのために、内側のループが数回に計算されたwords単語の文字の出現数の最小値、我々は、ループ処理から抜け出すことができるかもしれません。各単語の出現の最小最初の文字は、算出長さに記憶されておりwords、同じintアレイは、内側のループでは、あなたが直接通過できるint再びアレイを、その代わりに、すべての再カウントのそれぞれ。

public int[] numSmallerByFrequency2(String[] queries, String[] words) {
    int len = queries.length, len2 = words.length;
    int[] wordFreq = new int[len2];
    for (int j=0; j<len2; j++) {
        wordFreq[j] = minFrequency(words[j]);
    }
    int[] result = new int[len];
    for (int i=0; i<len; i++) {
        int query = minFrequency(queries[i]);
        int count = 0;
        for (int j=0; j<len2; j++) {
            if (query < wordFreq[j]) {
                count++;
            }
        }
        result[i] = count;
    }
    return result;
}

/**
 * 找到字符串中的最小字符的出现次数
 * @param s
 * @return
 */
public int minFrequency(String s) {
    int[] arr = new int[26];
    int count = 0;
    for (int i=0; i<s.length(); i++) {
        arr[s.charAt(i)-'a']++;
    }
    for (int j=0; j<26; j++) {
        if (arr[j] != 0) {
            count = arr[j];
            break;
        }
    }
    return count;
}


第三の溶液

以前のソリューションの両方のために、我々はそれを下に簡素化することができますか?たとえば、2は1つのループサイクルになりますか?1サイクルを変更するには、その後、計算queries文字列は、あなたがサイクルを使用していない、結果を得るために時間を必要とするとき、それは、配列内の値と同じです。

私たちが最初に次の観察第二の例。で処理されたwords単語は、配列を取得しますときwordFreq、新しい文字が再び、累積数を最小限に表示される、配列のインデックス番号を計数処理を行い、変更の下で行うには、この基準では、あなたは以下の4つを取得します:

count[4] = 1; //"aaaa"代表的单词
count[3] = 1; //"aaa"代表的单词
count[2] = 1; //"aa"代表的单词
count[1] = 1; //"a"代表的单词

観測の下に来るqueries配列、文字列"bbb""cc"行くとwords言葉の比較、次のルールがあります:

大于"bbb"的有1位,记为arr[3] = 1
大于"cc"的有2位,记为arr[2] = 2

あなたはその後、書き留めた場合:

大于1的有3位,arr[1] = 3
大于0的有4位,arr[0] = 4

我々は、と、それを発見したqueriesの指標としての文字列の出現数が最小arrの上方に、実際には、アレイcountのアレイ累積和の逆要素。

arr[3] = count[4] = 1;
arr[2] = arr[3] + count[3] = 1+1 = 2

すなわち:

arr[i-1] = arr[i]+count[i];

そのうちの原則を分析した後、残りの部分は、コードを書くことで、この溶液は、前の二つのソリューションの速度に比べてはるかに高速です。

public int[] numSmallerByFrequency3(String[] queries, String[] words) {
    int len = queries.length;
    int[] wordFreq = new int[11];
    for (String word : words) {
        wordFreq[minFrequency(word)]++;
    }
    int[] sum = new int[11];
    for (int i=sum.length-1; i>0; i--) {
        sum[i-1] = sum[i]+wordFreq[i];
    }
    int[] result = new int[len];
    for (int i=0; i<len; i++) {
        result[i] = sum[minFrequency(queries[i])];
    }
    return result;
}

/**
 * 找到字符串中的最小字符的出现次数
 * @param s
 * @return
 */
public int minFrequency(String s) {
    int[] arr = new int[26];
    int count = 0;
    for (int i=0; i<s.length(); i++) {
        arr[s.charAt(i)-'a']++;
    }
    for (int j=0; j<26; j++) {
        if (arr[j] != 0) {
            count = arr[j];
            break;
        }
    }
    return count;
}


概要

テーマ別のアルゴリズムは今更新したLeetCodeの特集記事のアルゴリズム269件の +記事、公衆番号]ダイアログボックスの返信[ データ構造とアルゴリズム ]、[ アルゴリズム ]、[ データ構造を記事のコレクションのシリーズを得るために、キーワードのいずれか]。

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

おすすめ

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