Loading

剑指offer一刷:字符串

剑指 Offer 05. 替换空格

难度:简单

方法一:遍历添加

class Solution {
    public String replaceSpace(String s) {
        StringBuilder res = new StringBuilder();
        for(Character c : s.toCharArray())
        {
            if(c == ' ') res.append("%20");
            else res.append(c);
        }
        return res.toString();
    }
}

作者:Krahets
链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/50c26h/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

时间复杂度:O(N),空间复杂度:O(N)。

方法二:原地修改

在 C++ 语言中, string 被设计成「可变」的类型(参考资料),因此可以在不新建字符串的情况下实现原地修改。

因为不是 Java 代码实现的,这里就不贴代码了。

时间复杂度:O(N),空间复杂度:O(1)。

剑指 Offer 58 - II. 左旋转字符串

难度:简单

方法一:字符串切片

class Solution {
    public String reverseLeftWords(String s, int n) {
        return s.substring(n, s.length()) + s.substring(0, n);
    }
}

作者:Krahets
链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/58eckc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

时间复杂度:O(N),空间复杂度:O(N)。

方法二:列表遍历拼接

class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuilder res = new StringBuilder();
        for(int i = n; i < s.length(); i++)
            res.append(s.charAt(i));
        for(int i = 0; i < n; i++)
            res.append(s.charAt(i));
        return res.toString();
    }
}

作者:Krahets
链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/58eckc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

时间复杂度:O(N),空间复杂度:O(N)。

方法三:字符串遍历拼接

class Solution {
    public String reverseLeftWords(String s, int n) {
        String res = "";
        for(int i = n; i < s.length(); i++)
            res += s.charAt(i);
        for(int i = 0; i < n; i++)
            res += s.charAt(i);
        return res;
    }
}

作者:Krahets
链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/58eckc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

时间复杂度:O(N),空间复杂度:O(N)。

运行时间:一 < 二 < 三。

方法四:三次翻转(C++)

由于 C++ 中的字符串是 可变类型 ,因此可在原字符串上直接操作实现字符串旋转,实现 O(1) 的空间复杂度。

代码略。(左神书上有类似题,用Java代码实现三次翻转达到 O(1) 的空间复杂度)

时间复杂度:O(N),空间复杂度:O(1)。

剑指 Offer 20. 表示数值的字符串

难度:中等

很恶心的题目。不多说了。使用有限自动状态机来做。详见题解

虽然我还是倾向于我自己的做法。。

题解代码如下:

class Solution {
    public boolean isNumber(String s) {
        Map[] states = {
            new HashMap<>() {{ put(' ', 0); put('s', 1); put('d', 2); put('.', 4); }}, // 0.
            new HashMap<>() {{ put('d', 2); put('.', 4); }},                           // 1.
            new HashMap<>() {{ put('d', 2); put('.', 3); put('e', 5); put(' ', 8); }}, // 2.
            new HashMap<>() {{ put('d', 3); put('e', 5); put(' ', 8); }},              // 3.
            new HashMap<>() {{ put('d', 3); }},                                        // 4.
            new HashMap<>() {{ put('s', 6); put('d', 7); }},                           // 5.
            new HashMap<>() {{ put('d', 7); }},                                        // 6.
            new HashMap<>() {{ put('d', 7); put(' ', 8); }},                           // 7.
            new HashMap<>() {{ put(' ', 8); }}                                         // 8.
        };
        int p = 0;
        char t;
        for(char c : s.toCharArray()) {
            if(c >= '0' && c <= '9') t = 'd';
            else if(c == '+' || c == '-') t = 's';
            else if(c == 'e' || c == 'E') t = 'e';
            else if(c == '.' || c == ' ') t = c;
            else t = '?';
            if(!states[p].containsKey(t)) return false;
            p = (int)states[p].get(t);
        }
        return p == 2 || p == 3 || p == 7 || p == 8;
    }
}

作者:Krahets
链接:https://leetcode.cn/leetbook/read/illustration-of-algorithm/5dkal2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 67. 把字符串转换成整数

难度:中等

根据题意,有以下四种字符需要考虑:

  1. 首部空格:删除之即可;
  2. 符号位:三种情况,即 ''+'' , ''−'' , ''无符号" ;新建一个变量保存符号位,返回前判断正负即可;
  3. 非数字字符:遇到首个非数字的字符时,应立即返回;
  4. 数字字符
    1. 字符转数字:“此数字的 ASCII 码”与“0 的 ASCII 码”相减即可;
    2. 数字拼接:若从左向右遍历数字,设当前位字符为 c,当前位数字为 x,数字结果为 res,则数字拼接公式为:

数字越界处理:

在每轮数字拼接前,判断 res 在此轮拼接后是否超过 2147483647,若超过则加上符号位直接返回。
设数字拼接边界 bndry = 2147483647 // 10 = 214748364,则以下两种情况越界:

这里 x > 7 判断非常巧妙,> 7 直接根据符号位返回 Integer.MAX_VALUE 或 Integer.MIN_VALUE,省得根据正负分情况判断 2 次。

class Solution {
    public int strToInt(String str) {
        int res = 0, bndry = Integer.MAX_VALUE / 10;
        int i = 0, sign = 1, length = str.length();
        if(length == 0) return 0;
        while(str.charAt(i) == ' ')
            if(++i == length) return 0;
        if(str.charAt(i) == '-') sign = -1;
        if(str.charAt(i) == '-' || str.charAt(i) == '+') i++;
        for(int j = i; j < length; j++) {
            if(str.charAt(j) < '0' || str.charAt(j) > '9') break;
            if(res > bndry || res == bndry && str.charAt(j) > '7')
                return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            res = res * 10 + (str.charAt(j) - '0');
        }
        return sign * res;
    }
}

作者:Krahets
链接:https://leetcode.cn/leetbook/read/illustration-of-algorithm/58mttv/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

时间复杂度:O(N),空间复杂度:O(1)。

posted @ 2022-05-02 11:49  幻梦翱翔  阅读(24)  评论(0)    收藏  举报