LeetCode - 字符串基础问题

字符串基础问题

709. 转换成小写字母

实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串。

示例 1:

输入: “Hello”
输出: “hello”
示例 2:

输入: “here”
输出: “here”
示例 3:

输入: “LOVELY”
输出: “lovely”

方法一

通过 ASCII 码表操作字符串即可。
a-z:97-122
A-Z:65-90
0-9:48-57

class Solution_709 {
    public String toLowerCase(String str) {
        if (str  == null || str.length() == 0) return str;
        int len  = str.length();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c >= 'A' && c <= 'Z'){
                sb.append((char)(c + 32));
            }else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    public String toLowerCase2(String str) {
        if (str == null || str.length() == 0) {
            return str;
        }
        char[] ch = str.toCharArray();
        for (int i = 0; i < str.length(); i++) {
            if (ch[i] >= 'A' && ch[i] <= 'Z') {
                ch[i] += 32;
            }
        }
        return String.valueOf(ch);
    }

}

方法2:位运算
思路:
用位运算的技巧:

大写变小写、小写变大写:字符 ^= 32;
大写变小写、小写变小写:字符 |= 32;
大写变大写、小写变大写:字符 &= 33;

class Solution {
    public String toLowerCase(String str) {
        if (str == null || str.length() == 0) {
            return str;
        }
        char[] ch = str.toCharArray();
        for (int i = 0; i < str.length(); i++) {
            ch[i] |= 32;
        }
        return String.valueOf(ch);
    }
}

58. 最后一个单词的长度

给定一个仅包含大小写字母和空格 ’ ’ 的字符串 s,返回其最后一个单词的长度。如果字符串从左向右滚动显示,那么最后一个单词就是最后出现的单词。

如果不存在最后一个单词,请返回 0 。

说明:一个单词是指仅由字母组成、不包含任何空格字符的 最大子字符串。

示例:

输入: “Hello World”
输出: 5

思路:

标签:字符串遍历

从字符串末尾开始向前遍历,其中主要有两种情况

第一种情况,以字符串 “Hello World” 为例,从后向前遍历直到遍历到头或者遇到空格为止,即为最后一个单词 “World” 的长度5

第二种情况,以字符串 "Hello World " 为例,需要先将末尾的空格过滤掉,再进行第一种情况的操作,即认为最后一个单词为 “World”,长度为5

所以完整过程为先从后过滤掉空格找到单词尾部,再从尾部向前遍历,找到单词头部,最后两者相减,即为单词的长度

时间复杂度:O(n),n为结尾空格和结尾单词总体长度

class Solution_58 {
    public int lengthOfLastWord(String s) {
        String y =s.trim();
        if (y.length() == 0) return 0;
        if (y.equals(" ")) return 0;
        StringBuilder sb = new StringBuilder();
        char[] c = y.toCharArray();
        int count = 0;
        for (int i = c.length - 1; i >= 0; i--) {
            if (c[i] != ' '){
                sb.append(c[i]);
            }
            if (c[i] == ' '){
                break;
            }
        }
        String m = sb.toString();
        return m.length();
    }


    public int lengthOfLastWord2(String s){
        if (s.length() == 0) return 0;
        int count = 0;
        for (int i = s.length() - 1; i >= 0; i--) {
            char c = s.charAt(i);
            if (c == ' ' && count == 0) continue;//如果当前count为0,证明后面都是空格‘ ’
            if (c != ' '){
                count++;
            }else { //当count!= 0且不是空格,退出
                break;
            }
        }
        return  count;
    }

    public int lengthOfLastWord3(String s) {
        String y =s.trim();
        if (y.length() == 0) return 0;
        if (y.equals(" ")) return 0;
        char[] c = y.toCharArray();
        int count = 0;
        for (int i = c.length - 1; i >= 0; i--) {
            if (c[i] == ' ' && count == 0) continue;     //如果当前count为0,证明后面都是空格‘ ’
            if (c[i] != ' '){
                count++;
            }else {
                break;
            }

        }
        return count;
    }

}

771. 宝石与石头

给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石。

J 中的字母不重复,J 和 S中的所有字符都是字母。字母区分大小写,因此"a"和"A"是不同类型的石头。

示例 1:

输入: J = “aA”, S = “aAAbbbb”
输出: 3
示例 2:

输入: J = “z”, S = “ZZ”
输出: 0

注意:

S 和 J 最多含有50个字母。
J 中的字符不重复。

解题思路

标签:字符串

首先对J进行遍历,将字符分别存到HashSet中,以便之后遍历S的时候查找

遍历S,并将每个字符与HashSet中的进行比对,如果存在,则结果ans++,遍历结束,返回ans

时间复杂度:O(m+n),m为J的长度,n为S的长度

暴力:

class Solution {
    public int numJewelsInStones(String J, String S) {
        int jewelsCount = 0;
        int jewelsLength = J.length(), stonesLength = S.length();
        for (int i = 0; i < stonesLength; i++) {
            char stone = S.charAt(i);
            for (int j = 0; j < jewelsLength; j++) {
                char jewel = J.charAt(j);
                if (stone == jewel) {
                    jewelsCount++;
                    break;
                }
            }
        }
        return jewelsCount;
    }
}

哈希表:

class Solution_771 {
    public int numJewelsInStones(String J, String S) {

        Set<Character> set = new HashSet<>();
        for (int i = 0; i < J.length(); i++) {
            set.add(J.charAt(i));
        }
        int ans = 0;
        for (int i = 0; i < S.length(); i++) {
            if (set.contains(S.charAt(i))){
                ans++;
            }
        }
        return ans;
    }
}

387. 字符串中的第一个唯一字符

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

示例:

s = “leetcode”
返回 0

s = “loveleetcode”
返回 2

在这里插入图片描述

思路
哈希表统计频率返回第一个频率为1字符的下标即可

class Solution {
    public int firstUniqChar(String s) {
        HashMap<Character,Integer> hm = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            hm.put(s.charAt(i),hm.getOrDefault(s.charAt(i),0) + 1);
        }
        for (int i = 0; i < s.length(); i++) {
            if (hm.get(s.charAt(i)) == 1){
                return i;
            }
        }
        return -1;
    }
}

8. 字符串转换整数 (atoi)——重点

自动机
在这里插入图片描述

class Solution {
    public int myAtoi(String str) {
        
        //去掉str前后的空格
        str = str.trim();
        //如果字符串的长度为否为0
        if (str.length() == 0){
            return 0;
        }
        //输入种类(+, -, 0-9以及其他)
        if (!Character.isDigit(str.charAt(0))
        && str.charAt(0) != '-' && str.charAt(0) != '+')
            return 0;
        /**
         * 把字符串转换成字符数组
         */

        Character[] arr = new Character[str.length()];
        //定义应该输出的答案,ans
        long ans = 0L;
        //把字符串分成字符存到数组中
        for (int i = 0; i < str.length(); i++) {
            char kk = str.charAt(i);
            arr[i] = kk;
            //System.out.print(arr[i]);
            //判断数组中元素的类型
            //System.out.println( "      类型:" + arr[i].getClass().toString());
            
        }



        //判断数组的第一个字符是否是‘-’,定义一个flag,之后可以用三元表达式进行正负数的反转
        boolean neg = arr[0].equals('-');

        //不是‘-’开头,则判断之后的数字是否是数字
        //判断第一个数数字是否是数字,是数字则返回0 ,不是数字则为1
        int i = !Character.isDigit(str.charAt(0))? 1 : 0;

        while (i < str.length() && Character.isDigit(str.charAt(i))) {
            //把字符的数字转换成integer类型的数字,可以减去‘0’;
            ans = ans * 10 + (str.charAt(i++) - '0');
            //不是负数,数值比int大,则返回int的最长长度
            if (!arr[0].equals('-') && ans > Integer.MAX_VALUE) {
                ans = Integer.MAX_VALUE;
                break;
            }
            //是负数,并且超过范围了,返回  INT_MAX (2^31 − 1) 或 INT_MIN (−2^31)
            if (arr[0].equals('-') && ans > 1L + Integer.MAX_VALUE) {
                //Integer.MAX_VALUE == 2^31 - 1,加1是因为负数则返回最小值-2^31(INT_MIN),最大值+1取反则为最小取值
                ans = 1L + Integer.MAX_VALUE;   
                break;
            }
        }


        if (arr[0].equals('-')){
            ans = ans * (-1);
        }

        return (int) ans;

    }

}
public int myAtoi(String str) {
    int index = 0, sign = 1, total = 0;
    //1. Empty string
    if(str.length() == 0) return 0;

    //2. Remove Spaces
    while(str.charAt(index) == ' ' && index < str.length())
        index ++;

    //3. Handle signs
    if(str.charAt(index) == '+' || str.charAt(index) == '-'){
        sign = str.charAt(index) == '+' ? 1 : -1;
        index ++;
    }    
    //4. Convert number and avoid overflow
    while(index < str.length()){
        int digit = str.charAt(index) - '0';
        if(digit < 0 || digit > 9) break;

        //check if total will be overflow after 10 times and add digit21
        if(Integer.MAX_VALUE/10 < total ||            
        	Integer.MAX_VALUE/10 == total && Integer.MAX_VALUE %10 < digit)
            return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;

        total = 10 * total + digit;
        index ++;
    }
    return total * sign;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值