LeetCode初级算法题——字符串类——算法总结

LeetCode初级算法字符串类——算法总结

PS:算法并非原创,总结的本意在于温故知新、巩固知识。侵删。

1、反转字符串
使用C++解答,代码如下:

class Solution {
public:
    void reverseString(vector<char>& s) {
        int n=s.size();
        for(int i=0;i<n/2;i++){
            swap(s[i],s[n-i-1]);  
        }
    }
};

算法解析:
简单调换数组头尾的元素,没啥算法,想起来用swap()函数就更简单了。

算法占用时空间资源:
在这里插入图片描述
在这里插入图片描述

2、整数反转
使用C++解答,代码如下:

class Solution {
public:
    int reverse(int x) {
        int result(0);
        while (x!=0) {
            if (result > INT_MAX / 10) {
                return 0;
            }
            if (result < INT_MIN / 10) {
                return 0;
            }
            result *=10;
            result += x % 10;
            x /= 10;
        }
        return result;
    }
};

算法解析:
常量INT_MAX和INT_MIN分别表示最大、最小整数,定义在头文件limits.h中。
INT_MAX = 2^31-1,INT_MIN= -2^31。两个if语句用来判断结果是否溢出,如果溢出将会直接返回0;
而正常情况下,为了完成整数的反转,定义一个result作为结果变量,一开始为0,每一次循环将x的个位取出,成为result的最低位,随着循环进行,result中每一次进行*10操作,使得x的越低的位数,成为result中位数越高的位数。循环在取到x的最高位时结束。
这个题目没啥难度,大一C语言基础课就做过类似的,可能还有更好的解法,但是我暂时没发现。

算法占用时空间资源:
在这里插入图片描述
在这里插入图片描述

3、字符串中的第一个唯一字符
使用python解答,代码如下:

class Solution:
    def firstUniqChar(self, s):
        """
        :type s: str
        :rtype: int
        """
        from collections import Counter
        if s and s.count(s[0])==1:
            return 0
        length = len(s) + 1
        s_dict = Counter(s)
        num = length
        for elem in s_dict:
            if s_dict[elem] == 1:
                elem_index = s.index(elem)
                if elem_index <= num:
                    num = elem_index
                    if num == 0:
                        break
        if num < length:
            return num
        else:
            return -1

算法解析:
基本思想还是使用字典,字典也的确在字数统计方面有着天然优势。经过counter(s)步骤得出s_dict字典,如果字典中某个元素为1,那么我们还需要将这个下标(使用 s.index(elem)
得出)和之前得到的结果比较,num用来存储下标,最中比较得出最小的下标。

算法占用时空间资源:
在这里插入图片描述
在这里插入图片描述

4、有效的字母异位词
使用python解答,代码如下:

class Solution:
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        dic1=collections.Counter(s)
        dic2=collections.Counter(t)
        return operator.eq(dic1,dic2)

算法解析:
使用字典,判断两个数生成的字典是不是相同,很直接的做法。
也可以选择先排序,然后比较,这样通过strcmp也可以实现。

算法占用时空间资源:
在这里插入图片描述
在这里插入图片描述

5、验证回文串
使用JAVA解答,代码如下:

class Solution {
     public boolean isPalindrome(String s) {
        char[] cha = s.toCharArray();
        int i = 0, j = cha.length - 1;
        while(i < j){
            if(!Character.isLetterOrDigit(cha[i]))
                i++;
            else if(!Character.isLetterOrDigit(cha[j]))
                j--;
            else
                if(Character.toLowerCase(cha[i]) == Character.toLowerCase(cha[j])){
                    i++;
                    j--;
                }else{
                    return false;
                }
        }
        return true;
}
}

算法解析:
基本算法思想是头尾逐个字母比较。Character.isLetterOrDigit(cha[i])从名字也看得出来这个是干啥的,也就是判断一个字符是不是字母或者数字。用在此处,实现两侧遍历当遇到符号时跳过。如果字母或者数字相等且未到达中点时,继续比较,否则结束比较,得出结论。

算法占用时空间资源:
在这里插入图片描述
在这里插入图片描述

6、字符串转换整数(atoi)
使用C++解答,代码如下:

class Solution {
public:
int myAtoi(string str) {

       int i=0, n=str.size();

       while(i<n&&str[i]==' ')
          i++;

        int sign=1;
        long res=0;
        if(str[i]=='-'||str[i]=='+'){
            sign=(str[i++]=='-')?(-1):1;
        }

        while(i<n&&str[i]>='0'&&str[i]<='9'){
            res=res*10+(str[i++]-'0');
            if(res*sign>INT_MAX)
                return INT_MAX;
            if(res*sign<INT_MIN)
                return INT_MIN;
        }
        return res*sign;
    }
};

算法解析:
首先通过遍历找到第一个非空符号,然后判断数字有无正负号,通过 sign=(str[i++]==’-’)?(-1):1;这行命令,如果str[i]是‘-’,那么让sign等于-1,否则sign等于 1 。整个语句就是判断s的正负号。此后的操作将数字字符转为数字,较为简单。INT_MAX和INT_MIN在整数反转中提到过。用来控制数据的转换范围。

算法占用时空间资源:
在这里插入图片描述
在这里插入图片描述

7、实现strStr()
使用JAVA解答,代码如下:

class Solution {
    public int strStr(String haystack, String needle) {
         return haystack.indexOf(needle);
    }
}

算法解析:
根据题目要求,其实使用数据结构中的KMP算法也可以胜任,但比较占内存空间。此处用JAVA进行解答,emmmm,算是一个捷径吧,希望自己以后能记住这个用法。不过此处应该是通过自己的编写实现这个函数功能的。
注意此题的讨论点:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

算法占用时空间资源:
在这里插入图片描述
在这里插入图片描述

8、外观数列
使用JAVA解答,代码如下:

class Solution {
    public String countAndSay(int n) {
        String str = "1";
        for (int i = 2; i <= n; i++) {
            StringBuilder builder = new StringBuilder();//新建一个string类用于拼接
            char pre = str.charAt(0);//取第一个字符
            int count = 1;//统计有几个相同的
            for (int j = 1; j < str.length(); j++) {
                char c = str.charAt(j);
                if (c == pre) {//后一个字符与前一个相同
                    count++;
                }
 else {
                    builder.append(count).append(pre);//拼接count个pre
                    pre = c;//前缀等于不同处
                    count = 1;
                }
            }
            builder.append(count).append(pre);//拼接count个pre
            str = builder.toString();//转换为string
        }
        return str;
    }
}

算法解析:
在str中,通过循环得出每一段相同字符的长度,然后进行字符串的拼接。然后取下一段相同字符,重复操作。两个遍历中,第一层的i遍历确定最终的字符串长度,第二次的j遍历确定字符中每段都得到遍历。每一次的i遍历中,字符串长度均会发生变化。

算法占用时空间资源:
在这里插入图片描述
在这里插入图片描述

9、最长公共前缀
使用C++解答,代码如下:

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if (strs.empty()) 
return "";
        for (int j = 0; j < strs[0].size(); ++j) {
            for (int i = 0; i < strs.size() - 1; ++i) {
                if (j >= strs[i].size() || j >= strs[i + 1].size() || strs[i][j] != strs[i + 1][j]) {
                    return strs[i].substr(0, j);
                }
            }
        }
        return strs[0];
    }
};

算法解析:
strs实际上是一个字符串组,包含多个字符串。j用来确定最长公共前缀的长度。当j大于某个字符串长度或者不再满足相等条件时,j为最终的长度,结果返回strs[i].substr(0,j),表示返回最长公共前缀。反之,j不断递增。如果遍历全部完成,说明第一个字符串全体均为最长公共前缀,返回strs[0]。

算法占用时空间资源:
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值