Niuke.com ブラシの質問

ced485cbb11e458d81a746890b32cf3f.gif

作者:流川メイプルノックコード

ブログホームページ:流川楓のブログ

コラム:私と一緒にJavaを学ぼう

引用:ハングリーでいて、愚かでいて

良いことをしたいなら、まずツールを研ぎ澄ます必要があります.大手メーカーからのオファーを獲得するための超強力なツールを紹介しましょう-Niuke.com

クリックして無料で登録し、私と一緒に質問をブラッシングしてください    

記事ディレクトリ

数値を表す文字列

スペースを置き換える

フィボナッチ数列

 数値が昇順の配列に出現する回数


数値を表す文字列

文字列 str が数値 (科学表記法、小数、整数を含む) を表しているかどうかを判断する関数を実装してください。

科学表記法(順番) の数値は、次の部分に分けることができます。

1. いくつかのスペース

2. 整数または小数

3. (オプション) 'e' または 'E' に続く整数 (正または負)

4. いくつかのスペース

小数 (順番に) は、次の部分に分けることができます。

1. いくつかのスペース

2. (オプション) 符号文字 ('+' または '-')

3. 次の記述形式のいずれかになります。

3.1 少なくとも 1 つの数字の後にドット「.」が続く

3.2 少なくとも 1 つの数字の後にドット「.」が続き、その後に少なくとも 1 つの数字が続く

3.3 ドット「.」の後に少なくとも 1 つの数字が続く

4. いくつかのスペース

整数 (順番に) は、次の部分に分割できます。

1. 複数のスペース
2. (オプション) 符号文字 ('+' または '-')

3. 少なくとも 1 桁

4. いくつかのスペース

たとえば、文字列 ["+100","5e2","-123","3.1416","-1E-16"] はすべて数値を表します。

しかし ["12e","1a3.14","1.2.3","+-5","12e+4.3"] は数値ではありません。

ヒント:

1.1 <= str.length <= 25

2.str には、英字 (大文字と小文字)、数字 (0-9)、プラス記号 '+' 、マイナス記号 '-' 、スペース ' ' またはドット '.' のみが含まれます。

3. ユースケースが数値で表せるかどうか疑問がある場合は、python の print(float(str)) を使用して確認できます

高度: 時間の複雑さ O(n)\O(n)、空間の複雑さ O(n)\O(n) 

アイデア:

最初のトリム、文字列の先頭と末尾のスペースを削除します

. は 1 回だけ表示でき、e の前にのみ表示できます

e は 1 回だけ使用でき、前に数字を付ける必要があります

+ - の先頭または e の後にのみ使用できます

スペース、trim で処理、途中にスペースがある場合、失敗するとすぐに戻ります

ブール値を使用して各状況が発生するかどうかを示し、成功した状況のみを書き込みます

答え:

    public boolean isNumeric (String str) {
     
        str = str.trim();
        //用boolean来表示每一个情况是否出现,是否出现一次(用!XXX来判断)
        boolean numFlag = false, dotFlag = false, eFlag = false, plusFlag = false;
        //只写成功的情况
        for(int i = 0; i < str.length(); i++){
            if(str.charAt(i) >= '0' && str.charAt(i) <= '9'){
                numFlag = true;
            }else if(str.charAt(i) == '.' && !dotFlag && !eFlag){
                dotFlag = true;
            }else if((str.charAt(i) == 'e' || str.charAt(i) == 'E') &&
                     !eFlag && numFlag){
                eFlag = true;
                //处理132e这种情况
                numFlag = false;
            }else if((str.charAt(i) == '+' || str.charAt(i) == '-') && 
                     (i == 0 || str.charAt(i-1) == 'e' || str.charAt(i-1) == 'E')){
                //什么也不干
            }else {
                return false;
            }
        }
        return numFlag;
    }

スペースを置き換える

文字列 s の各スペースを "%20" に置き換える関数を実装してください。

たとえば、文字列が We Are Happy. の場合、置換される文字列は We%20Are%20Happy になります。

データ範囲: 0 \le len(s) \le 1000 \0≤len(s)≤1000 . 文字列内の文字が英大文字、英小文字、およびスペースのいずれかであることを確認してください。

方法1

アイデア: 最初に文字列を 1 文字に変換する

ここで必要なのは、文字列内のスペースを %20 に置き換えることです. これを実現する 1 つの方法は、一時配列を適用して、文字列の各文字をトラバースすることです. スペースでない場合は、トラバースした文字を一時配列. 、スペースの場合は、一時配列に「%」、「2」、「0」の 3 文字をそれぞれ追加し、最後に一時配列を文字列に変換します。

    public String replaceSpace(String s) {
        int length = s.length();
        char[] array = new char[length * 3];
        int index = 0;
        for (int i = 0; i < length; i++) {
            char c = s.charAt(i);
            if (c == ' ') {
                array[index++] = '%';
                array[index++] = '2';
                array[index++] = '0';
            } else {
                array[index++] = c;
            }
        }
        String newStr = new String(array, 0, index);
        return newStr;
    }

時間の複雑さ: O(n)、すべての文字が 1 回トラバースされる
スペースの複雑さ: O(n)、n*3 の配列が必要 

方法 2

アイデア: StringBuilder を使用する

文字列の各文字を 1 つずつ StringBuilder に追加します。スペースが見つかった場合は、%20 に置き換えます

    public String replaceSpace(String s) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' ')
                stringBuilder.append("%20");
            else
                stringBuilder.append(s.charAt(i));
        }
        return stringBuilder.toString();
    }

時間の複雑さ: O(n)、すべての文字が 1 回トラバースされる
スペースの複雑さ: O(n)、StringBuilder が必要とするスペース

フィボナッチ数列

フィボナッチ数列は誰もが知っていますが、正の整数 n を入力する必要があるので、フィボナッチ数列の n 番目の項目を出力してください。

フィボナッチ数列は、 fib(x)=\left\{ \begin{array}{rcl} 1 & {x=1,2}\\ fib(x-1)+fib(x-2) & を満たす数列です。 {x>2}\\ \end{array} \right.fib(x)={1fib(x−1)+fib(x−2) x=1,2x>2 配列

データ範囲: 1\leq n\leq 401≤n≤40

要件: 空間の複雑さ O(1)O(1)、時間の複雑さ O(n)O(n) 、この問題には時間の複雑さ O(logn)O(logn) ソリューションもあります

説明を入力してください:

正の整数 n

戻り値の説明:

正の整数を出力します。

方法1

アイデア: 反復加算 (推奨)

動的計画法アルゴリズムの基本的な考え方は次のとおりです。解決する問題をいくつかの相互に関連するサブ問題に分解し、最初にサブ問題を解決し、次にこれらのサブ問題の解決策から元の問題の解決策を取得します。繰り返される副問題については、最初に遭遇したときにのみ解決し、答えを保存しておけば、再び遭遇したときに答えを直接参照できるため、再度解決する必要はありません。動的計画法のアルゴリズムは、問題の解決策を一連の決定の結果として扱います

フィボナッチ数列の初期化の 1 番目と 2 番目の項目は両方とも 1 で、式によれば 0 番目の項目は 0 であり、フィボナッチの式に従って nnn 番目の項目に累積できます。

特定の方法:

1: 2 項目未満のシーケンス、n を直接返す

2: アイテム 0 を初期化し、アイテム 1 はそれぞれ 0、1 です

3: 2番目の項目から開始し、式に従って徐々に累積し、常に次の項目の最初の2つの項目になるように合計数を更新します

public class Solution {
    public int Fibonacci(int n) {
        //从0开始,第0项是0,第一项是1
        if(n <= 1)    
             return n;
         int res = 0;
         int a = 0;
         int b = 1;
         //因n=2时也为1,初始化的时候把a=0,b=1
         for (int i = 2; i <= n; i++){
         //第三项开始是前两项的和,然后保留最新的两项,更新数据相加
             res = (a + b);
             a = b;
             b = res;
         }
        return res;
    }
}

方法 2

アイデア: 再帰

1. n < 2 の場合、n を直接返す

2. 再帰アルゴリズム: フィボナッチ(n-1) + フィボナッチ(n-2);

利点、コードがシンプルで書きやすい、欠点: 遅い、タイムアウトする 時間の複雑さ: O(2^n) スペースの複雑さ: 再帰スタックのためのスペース

public class Solution {
    public int Fibonacci(int n) {
        if (n < 2){
            return n;
        }
        
        return Fibonacci(n-1) + Fibonacci(n-2);
    }
}

 数値が昇順の配列に出現する回数

長さ n の非降順配列と非負の整数 k が与えられた場合、k が配列に現れる回数をカウントするように依頼します

データ範囲: 0 \le n \le 1000 , 0 \le k \le 1000≤n≤1000, 0≤k≤100, 配列内の各要素の値は 0 \le val \le 1000≤val の要件を満たしています≤100
: 空間複雑度 O(1)O(1)、時間複雑度 O(logn)O(logn)

方法: 二分法 (推奨)

分割統治とは「分割統治」を意味し、「分割」とは、大規模で複雑な問題を、性質は同じだが小規模な複数のサブ問題に分割することを指し、サブ問題は、問題が解決できるまでこのように分割され続けます。簡単に解決できる; 」は、下位の問題を個別に扱うことを指します。部分問題を分割して解決した後、元の問題の解決策は解決策をマージすることで得られるため、分割と解決のプロセス全体が再帰によって実装されることがよくあります。

アイデア:

data は非降順配列なので順序付けられています. このとき二分探索を使うことが考えられます. ただし、配列には複数の k が含まれる場合があり、探しているのは、通常の二分法で k が表示される場所ではなく、k が表示される左境界と k が表示される右境界です。k よりちょうど小さい数の位置と k より少し大きい数の位置を見つけることができればいいのですが。

また、配列は整数でいっぱいなので、二分探索を使用して k+0.5k+0.5k+0.5 が表示される位置と k−0.5k-0.5k−0.5 が表示される位置を見つけて、 two は k の出現回数です

特定の方法:

1: 配列内の要素の位置を見つける二分探索関数を作成します。間隔の中点値を毎回確認し、中点との比較に基づいて次の間隔を決定します。

2: k+0.5 と k-0.5 が現れる位置をそれぞれ二分探索で求める. 真ん中の部分はすべて k であり, 計算回数を引くことができる.

public class Solution {
    //二分查找
    private int bisearch(int[] data, double k){ 
        int left = 0;
        int right = data.length - 1;
        //二分左右界
        while(left <= right){ 
            int mid = (left + right) / 2;
            if(data[mid] < k)
                left = mid + 1;
            else if(data[mid] > k)
                right = mid - 1;
        }
        return left;
    }
    public int GetNumberOfK(int [] array , int k) {
        //分别查找k+0.5和k-0.5应该出现的位置,中间的部分就全是k
        return bisearch(array, k + 0.5) - bisearch(array, k - 0.5);
    }
}

時間計算量: O(log2n)O(log_2n)O(log2 n)、nnn は配列の長さ、2 つのバイナリ検索、バイナリ検索の計算量は O(log2n)O(log_2n)O(log2 n)

スペースの複雑さ: O(1)O(1)O(1)、定数レベル変数、追加の補助スペースなし

「この問題の共有はこちらです。ブロガーに 3 つのリンクを提供することを忘れないでください。あなたのサポートが私の創造の最大の原動力です!

ced485cbb11e458d81a746890b32cf3f.gif

おすすめ

転載: blog.csdn.net/chenchenchencl/article/details/126454644