58. 最后一个单词的长度

小目标:百篇题解之六,破百开源成库。关注我(Github力扣),即可获取最新题解。
微信二维码

题目描述

给你一个字符串 s,由若干单词组成,单词之间用空格隔开。返回字符串中最后一个单词的长度。如果不存在最后一个单词,请返回 0 。
单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。

示例 1

输入:s = "Hello World"
输出:5

示例 2

输入:s = " "
输出:0

提示
1 <= s.length <= 104
s 仅有英文字母和空格 ' ' 组成

相关信息

  • 难度:简单
  • 标签:字符串

题解

本题是名副其实的简单题,作为老API调用怪,我直接几个API一把梭就搞定了,很快啊~嘿嘿,好了,不皮了。本题主要需要处理的情况有三种:

  1. "Hello Word":这是比较正常的情况,最后的位置存在单词。
  2. "Hello Word ":这种情况就是以空格结尾,但是空格之前有单词存在,所以 Word 应该是它的最后一个单词,这一点在题目的描述中表述得不是很清楚。
  3. " ":这种情况就是纯的空字符串,直接返回零0⃣️。

方法一:双指针

首先,我们从最原始的写法开始吧,然后一步步用API替代。

第一种实现思路,尾部指针从尾部开始,忽略尾部空格,指向尾部第一个非空格字符,然后头部指针从尾部出发,一直移动,直到遇见第一个空字符。返回尾部指针和头部指针之间的差值,即为单词长度。

/**
执行用时: 84 ms
内存消耗: 37.6 MB
 */
var lengthOfLastWord = function(s) {
    let end = s.length - 1;//尾部指针
    while(end >= 0 && s[end] == ' ') end--;//忽略尾部空格
    if(end < 0) return 0;
    let start = end;//头部指针出发
    while(start >= 0 && s[start] != ' ') start--;
    return end - start;
};

上边这种实现方式不太好的是使用了两次循环,不过一般尾部空格不会太多,所以实际影响也还好。

第二种实现方式就是将两次循环压缩到了一次循环,直接从尾部向头部循环一次,从第一个非空格字符开始计数,一旦再次遇到空格便结束循环。

/**
执行用时: 72 ms
内存消耗: 37.6 MB
*/
var lengthOfLastWord = function(s) {
    let count=0;
    for(let i=s.length-1;i>-1;i--){
        if(s[i]===' '){
            if(count==0)continue;//count为零时便一直跳过末尾的空字符
            break//count非零之后,第二次遇到空字符就结束
        }
        count++
    }
    return count;
};

从结果可以看出,这种实现方法确实有所提升。

另外,有同学会在函数体首部单独判断 s===' ',然后直接返回 0;我个人认为没有这个必要,因为所有遍历都是从尾部开始的,空字符串相比其他状况已经缩减了许多步骤,相比于直接返回0,并没有多处太多处理时间。经过我实际测试,弃掉这个判断,函数运行速度反而提升了,非常玄学。总之后,并非所有特殊情况,在函数体首部单独判断处理之后都能提升大幅度提升运行速率,应视具体情况而定。

方法二:开启 API 大赏

filter+split

/**
执行用时: 64 ms
内存消耗: 37.7 MB
 */
var lengthOfLastWord = function(s) 
    //分割后空数组全部筛去
    let words = s.split(' ').filter((item)=>item != '')
    //注意如果原数组全部为空格,筛选后words为空数组
    return words.length != 0?words[words.length-1].length:0
};

trim+split+reserve

/*
执行用时: 76 ms
内存消耗: 38.1 MB
*/
//这样反转数组还是比较耗时耗空间的
var lengthOfLastWord = function(s) {
    return s.trim().split(' ').reverse()[0].length
    //trim 去除首尾空格;split 按空格分割,reverse 反转数组。
};

trim + split+pop

/*
执行用时: 108 ms
内存消耗: 37.7 MB
*/
//果然开启API之后,运行速度会降很多,但我认为这是我目前想到的最简单的写法
var lengthOfLastWord = function(s) {
    return s.trim().split(" ").pop().length;
  //trim 去除首尾空格;split 按空格分割,pop弹出尾部单词
};

以上就是本题的所有题解啦,感谢你能看到这里,如果本文对你有所帮助的话,别忘了给一个 Star 嗷~
如果你对题解中的代码有不一样的优化意见,也欢迎你在 issue 中指出~
最重要的是不要忘了点点关注嗷(Github力扣),以便获取我最新的题解以及文章通知。

参考文章: