58. 最后一个单词的长度
给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。

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

 

示例 1:

输入:s = "Hello World"
输出:5
解释:最后一个单词是“World”,长度为5。
示例 2:

输入:s = "   fly me   to   the moon  "
输出:4
解释:最后一个单词是“moon”,长度为4。
示例 3:

输入:s = "luffy is still joyboy"
输出:6
解释:最后一个单词是长度为6的“joyboy”。
 

提示:

1 <= s.length <= 104
s 仅有英文字母和空格 ' ' 组成
s 中至少存在一个单词
题解
int lengthOfLastWord(char* s) {
    int now = strlen(s) - 1;
    int num = 0;
    printf("now = %d num = %d s[0] = %c",now,num,s[0]);
    while(now >=0 && (s[now] != ' ' || num == 0)){
        printf("\nwhile");
        if(s[now] != ' ')
            num++;
        now--;
        printf("\nnum = %d now = %d",num,now);
    }
    printf("num = %d",num);
    return num;
}

从后往前遍历直到第一个空格停止计数即可,注意考虑后面一段全为空格的情况 (忽略计数), 以及 now<0 会导致数组越界,此时根据与或特性,将 "now >= 0" 的条件写在前面即可避免

14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""。

 

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
 

提示:

1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] 仅由小写英文字母组成
题解
char* longestCommonPrefix(char** strs, int strsSize) {
    // 如果字符串数组为空,直接返回空字符串
    if (strsSize == 0) {
        return "";
    }
    
    // 计算第一个字符串的长度
    int len = strlen(strs[0]);
    
    // 遍历第一个字符串的每个字符
    for (int i = 0; i < len; i++) {
        // 逐个与其他字符串的相同位置字符比较
        for (int j = 1; j < strsSize; j++) {
            if (strs[j][i] != strs[0][i]) {
                // 如果不匹配,截取前缀并返回
                char* dest = (char*)malloc(i + 1);
                strncpy(dest, strs[0], i);
                dest[i] = '\0'; // 添加字符串结束符
                return dest;
            }
        }
    }
    
    // 如果所有字符串都匹配,返回第一个字符串
    return strs[0];
}

上述方法为纵向比较,值得注意的是首先进行判空防止无意义的计算,以及在循环函数外将字符串长度计算出来。最后就是复制字符串的方法

以下还有另一种方法 -- 横向比较法

将每个字符串与第一个字符串相比较,若不同就将此位置改为 "\0", 这样输出的字符串遇到第一个 "\0" 就停止,即为最短公共字符串了,具体代码如下:

char* longestCommonPrefix(char** strs, int strsSize) {
    // 如果字符串数组为空,直接返回空字符串
    if (strsSize == 0) {
        return "";
    }
    
    // 将第一个字符串作为模板
    char* prefix = strs[0];
    
    // 遍历其他字符串
    for (int i = 1; i < strsSize; i++) {
        // 逐个字符比较
        int j = 0;
        while (prefix[j] && strs[i][j] && prefix[j] == strs[i][j]) {
            j++;
        }
        // 截取前缀
        prefix[j] = '\0';
    }
    
    return prefix;
}
当比较纵向比较和横向比较这两种方法时,我们可以考虑它们的优势和局限性。

纵向比较:
优势:
简单直接:从第一个字符串开始,逐个字符地与其他字符串的相同位置的字符进行比较。
代码清晰:不需要额外的循环变量,代码结构清晰易懂。
适用性广泛:适用于不同长度的字符串数组。
局限性:
效率较低:如果第一个字符串很长,需要逐个字符地与其他字符串比较,可能会导致不必要的计算。
不适用于空数组:如果输入的字符串数组为空,需要额外处理。
横向比较:
优势:
效率较高:将第一个字符串作为模板,逐个字符地与其他字符串的相同位置的字符进行比较,避免了多次计算字符串长度。
一次遍历:只需要一次遍历其他字符串,而不是逐个字符地比较。
局限性:
需要额外的循环变量:需要一个循环变量来遍历其他字符串。
不适用于不同长度的字符串数组:如果其他字符串的长度不一致,需要额外处理。
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

KagurazakaAsahi 微信支付

微信支付