Jianzhi オファーの第 2 版: ロボットの可動範囲、正規表現の一致、および値を表す文字列

13. ロボットの可動範囲

タイトル: 座標 [0,0] から座標 [m-1,n-1] までの m 行 n 列の正方形が地面にあります。ロボットは座標 [0, 0] のグリッドから移動を開始し、そのたびに上下左右に 1 つのグリッドを移動できます (グリッドの外に移動することはできません)。 k グリッドより大きい行座標と列座標の桁。たとえば、k が 18 の場合、3+5+3+7=18 であるため、ロボットは正方形 [35, 37] に入ることができます。ただし、3+5+3+8=19 であるため、正方形 [35, 38] には入れません。ロボットはいくつのグリッドに到達できますか?
例 1:
入力: m = 2、n = 3、k = 1
出力: 3

class Solution {
    
    
    boolean[][] visited;  // 存储每个格子是否被访问过
    int res = 0;  // 记录可到达的格子数
    int m;  // 行数
    int n;  // 列数

    public int movingCount(int m, int n, int k) {
    
    
        if (m == 0) {
    
      // 如果行数为0,返回0
            return 0;
        }
        this.m = m;
        this.n = n;

        visited = new boolean[m][n];  // 初始化visited数组
        dfs(0, 0, k);  // 从(0, 0)开始dfs搜索
        return res;  // 返回可到达的格子数
    }

    private void dfs(int i, int j, int k) {
    
    
        if (i < 0 || j < 0 || i >= m || j >= n || check(i, j, k) || visited[i][j]) {
    
      // 如果i或j越界、格子的数字和大于k、或者格子已经被访问过,返回
            return;
        }

        res++;  // 可到达的格子数加1
        visited[i][j] = true;  // 标记格子(i, j)已经被访问过
        dfs(i + 1, j, k);  // 向下搜索
        dfs(i - 1, j, k);  // 向上搜索
        dfs(i, j + 1, k);  // 向右搜索
        dfs(i, j - 1, k);  // 向左搜索
        //不能回头
        //visited[i][j] = false;
    }

    private boolean check(int i, int j, int k) {
    
      // 判断格子(i, j)的数字和是否大于k
        int res = 0;
        while (i != 0) {
    
    
            res += i % 10;
            i /= 10;
        }

        while (j != 0) {
    
    
            res += j % 10;
            j /= 10;
        }

        if (res > k) {
    
    
            return true;
        } else {
    
    
            return false;
        }
    }
}

19. 正規表現マッチング

タイトル: 「.」と「 」を含む正規表現を照合する機能を実装してください。パターン内の文字「.」は任意の文字を意味し、「」は前の文字が何度でも (0 回を含む) 出現できることを意味します。この質問では、一致とは、文字列のすべての文字がパターン全体に一致することを意味します。たとえば、文字列「aaa」はパターン「aa」および「ab ac a」に一致しますが、「aa.a」または「ab*a」には一致しません。
例 1:
入力:
s = "aa"
p = "a"
出力: false
説明: "a" は "aa" の文字列全体と一致することはできません。

class Solution {
    
    
    public boolean isMatch(String s, String p) {
    
    
        // 获取字符串s和p的长度。
        int m = s.length();
        int n = p.length();
        // 创建一个二维布尔数组来存储子问题的结果。
        boolean[][] dp = new boolean[m + 1][n + 1];
        // 设置第一个元素的初始值为true。
        dp[0][0] = true;
        // 当p为空时,设置第一行的初始值。
        for (int i = 2; i <= p.length(); i++) {
    
    
            if (p.charAt(i - 1) == '*') {
    
    
                dp[0][i] = dp[0][i - 2];
            }
        }
        // 遍历整个dp数组,并根据递推关系填充它。
        for (int i = 1; i <= m; i++) {
    
    
            for (int j = 1; j <= n; j++) {
    
    
                // 如果p中的当前字符不是'*',我们需要检查s和p中的当前字符是否匹配。
                if (p.charAt(j - 1) != '*') {
    
    
                    if (p.charAt(j - 1) == s.charAt(i - 1) || p.charAt(j - 1) == '.') {
    
    
                        dp[i][j] = dp[i - 1][j - 1];
                    }
                } // 如果p中的当前字符是'*',有两种情况需要考虑。
                else {
    
    
                    // 如果p中的前一个字符不匹配s中的当前字符且不是'.',则可以跳过p中的最后两个字符。
                    if (p.charAt(j - 2) != s.charAt(i - 1) && p.charAt(j - 2) != '.') {
    
    
                        dp[i][j] = dp[i][j - 2];
                    } // 如果p中的前一个字符匹配s中的当前字符或是'.',则有三种可能的情况需要考虑。
                    else {
    
    
                        dp[i][j] = dp[i][j - 1] || dp[i][j - 2] || dp[i - 1][j];
                    }
                }
            }
        }
        // 返回最后一个子问题的结果。
        return dp[m][n];
    }
}

20. 数値を表す文字列

質問: 文字列が値 (整数と小数を含む) を表すかどうかを判断する関数を実装してください。
値 (順番) は次の部分に分割できます:
スペース
10 進数または整数
(オプション) 'e' または 'E' の後に整数が続きます
スペース
10 進数 (順番) は次の部分に分割できます:
(オプション)
次のいずれかの形式の符号文字 (「+」または「-」) :
少なくとも 1 つの数字の後にピリオド「.」が続く
少なくとも 1 つの数字の後にピリオド「.」が続き、少なくとも 1 つの数字が
続くドット「.」の後に少なくとも 1 桁の数字が続く 整数
(順序どおり) は、次の部分に分割できます:
(オプション) 符号文字 (「+」または「-」)
少なくとも 1 つの数字
部分 値の列挙 次のように:
[ 「+100」、「5e2」、「-123」、「3.1416」、「-1E-16」、「0123」]
いくつかの非値は次のようにリストされています:
[「12e」、「1a3.14」 , “ 1.2.3", "±5", "12e+5.4"]
例 1:
入力: s = "0"
出力: true

アイデア分析: 3 つのブール変数 isNum、isDot、isE を使用して、文字列に数字、小数点、指数記号があるかどうかを記録します。具体的には、文字にトラバースする場合、それが数値の場合は isNum を true に設定し、それが小数点であり、小数点と指数記号が以前に出現していない場合は isDot を true に設定し、指数記号の場合は isDot を true に設定します。数値が前にあり、指数記号がない場合は、isE を true に、isNum を false に設定します; プラス記号またはマイナス記号の場合は、文字列の先頭または指数記号の直後に表示する必要があります; 次の場合は false を返しますは、数値、小数点、指数記号、正符号または負符号ではありません。最後に、文字列に数字があるかどうかを示す isNum の値を返します。
時間計算量: O ( n ) O(n)O(n),其中 n n アルゴリズムは文字列内の各文字を反復処理する必要があるため、 nは文字列の長さです。
スペースの複雑さ:O ( 1 ) O(1)O ( 1 )は、アルゴリズムが 3 つのブール変数を格納するために一定量の余分なスペースのみを使用するためです。

class Solution {
    
    
    public boolean isNumber(String s) {
    
    
        // 去除字符串两端的空格。
        s = s.trim();
        // 如果字符串为空或长度为0,则返回false。
        if (s == null || s.length() == 0) {
    
    
            return false;
        }
        // 初始化三个布尔变量,用于记录字符串中是否有数字、小数点和指数符号。
        boolean isNum = false;
        boolean isDot = false;
        boolean isE = false;
        // 遍历字符串中的每个字符。
        for (int i = 0; i < s.length(); i++) {
    
    
            // 如果当前字符是数字,则将isNum设置为true。
            if (Character.isDigit(s.charAt(i))) {
    
    
                isNum = true;
            } // 如果当前字符是小数点,并且之前没有出现过小数点和指数符号,则将isDot设置为true。
            else if (s.charAt(i) == '.' && !isDot && !isE) {
    
    
                isDot = true;
            } // 如果当前字符是指数符号,并且之前出现过数字但没有出现过指数符号,则将isE设置为true,并将isNum设置为false(因为指数符号的出现意味着当前数字已经结束了)。
            else if ((s.charAt(i) == 'e' || s.charAt(i) == 'E') && isNum && !isE) {
    
    
                isE = true;
                isNum = false;
            } // 如果当前字符是加号或减号,则它必须出现在字符串的开头或紧接着指数符号之后。
            else if (s.charAt(i) == '+' || s.charAt(i) == '-') {
    
    
                if (i != 0 && s.charAt(i - 1) != 'e' && s.charAt(i - 1) != 'E') {
    
    
                    return false;
                }
            } // 如果当前字符不是数字、小数点、指数符号或加减号,则返回false。
            else {
    
    
                return false;
            }
        }
        // 返回isNum的值,表示字符串中是否有数字。
        return isNum;
    }
}

おすすめ

転載: blog.csdn.net/weixin_51405802/article/details/130323594