面试经典150题——最后一个单词的长度
目录
题目链接:58. 最后一个单词的长度 - 力扣(LeetCode)
题目描述
示例
提示:
解法一:反向遍历
Java写法:
C++写法:
解法二:逆天解法
思路
存在的问题
总结
题目链接:58. 最后一个单词的长度 - 力扣(LeetCode)
注:下述题目描述和示例均来自力扣
题目描述
给你一个字符串 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 <= 10^4
s
仅有英文字母和空格' '
组成s
中至少存在一个单词
解法一:反向遍历
- 去除尾部的空格:
- 使用
std::string
的find_last_not_of
方法找到最后一个不是空格的字符的索引。 - 然后使用
erase
方法从该索引的下一个位置开始删除,直到字符串末尾,这样就去除了尾部的所有空格。
- 使用
- 检查字符串是否为空:
- 调用
empty
方法来检查处理后的字符串是否为空。 - 如果为空,说明原字符串只包含空格,没有实际的单词,因此返回0。
- 调用
- 查找最后一个空格的位置:
- 使用
find_last_of
方法在字符串中查找最后一个空格的索引。 - 如果找不到空格(即返回
std::string::npos
),说明整个字符串就是一个单词,或者整个字符串为空(但已经在第2步中处理过了)。
- 使用
- 计算最后一个单词的长度:
- 如果找到了空格,那么最后一个单词就是空格之后的部分。
- 因此,最后一个单词的长度就是字符串的总长度减去最后一个空格的索引再减1(因为索引是从0开始的,且我们不希望包括空格本身在内)。
- 如果没有找到空格,说明整个字符串就是一个单词,直接返回字符串的长度即可。
这个思路的关键在于先对字符串进行预处理(去除尾部空格),然后利用字符串的查找功能来定位最后一个空格的位置,最后根据这个位置来计算最后一个单词的长度。这种方法既简单又高效,能够很好地解决问题。
Java写法:
class Solution {
public int lengthOfLastWord(String s) {
// 去除字符串尾部的空格
s = s.trim();
// 如果字符串为空,则最后一个单词的长度为0
if (s.length() == 0) {
return 0;
}
// 从字符串末尾开始向前遍历,找到最后一个空格的位置
int length = 0;
for (int i = s.length() - 1; i >= 0; i--) {
// 如果当前字符不是空格,则增加单词长度
if (s.charAt(i) != ' ') {
length++;
}
// 如果当前字符是空格,且已经计算过单词长度(即length不为0),则跳出循环
else if (length > 0) {
break;
}
}
return length;
}
}
C++写法:
class Solution {
public:
int lengthOfLastWord(string s) {
// 去除字符串尾部的空格
s.erase(s.find_last_not_of(' ') + 1);
// 如果字符串为空,则最后一个单词的长度为0
if (s.empty()) {
return 0;
}
// 从字符串末尾开始向前遍历,找到最后一个空格的位置
size_t lastSpaceIndex = s.find_last_of(' ');
if (lastSpaceIndex == std::string::npos) {
// 如果没有找到空格,说明整个字符串就是一个单词
return s.length();
} else {
// 返回最后一个单词的长度
return s.length() - lastSpaceIndex - 1;
}
}
};
解法二:逆天解法
这题还是很简单的嘛,但是我看见逆天网有的逆天代码了额如下
class Solution {
public int lengthOfLastWord(String s) {
return s.trim().length()-s.trim().lastIndexOf(" ")-1;
}
}
思路
- 去除首尾空格:使用
trim()
方法去除字符串s
首尾的所有空格字符。 - 计算总长度:使用
trim()
方法后的字符串的length()
方法来获取去除空格后的字符串长度。 - 查找最后一个空格的位置:再次使用
trim()
方法(注意这里实际上是多余的,因为trim()
已经在前一步调用过了,但在这个表达式中它会再次执行)后的字符串的lastIndexOf(" ")
方法来查找最后一个空格的索引。 - 计算单词长度:通过总长度减去最后一个空格的索引(需要再减1,因为索引是从0开始的,并且我们不想包括空格在内)来尝试获取最后一个单词的长度。
存在的问题
-
多余的
trim()
调用:在表达式中,s.trim()
被调用了两次,这是不必要的,因为它增加了不必要的计算开销,并且如果trim()
方法有副作用(尽管在这个场景中它没有),那么这种用法可能会引入问题。 -
错误处理最后一个单词:如果字符串的最后一个字符不是空格(即整个字符串就是一个单词,或者除了最后一个单词外没有其他空格),那么
lastIndexOf(" ")
将返回-1
(因为找不到空格)。此时,length() - (-1) - 1
会导致错误的计算结果,因为length() - (-1)
实际上是字符串的总长度加1,这显然是不正确的。
总结
一个算法的实现方式很多,比如如果你这里使用python来解决的话,会有一些方法可以直接去除长空格,然后你就可以切割字符串了,最后取出最后一个值不就好啦~~