Longest Word in a Sentence
Description
Given a sentence s, return its longest word. A word is a run of characters that aren't spaces, and words are separated by one or more spaces. If several words are equally long, return the first of them.
Examples
Example 1
Input: s = "I love programming"
Output: "programming"
Explanation: programming has 11 characters, more than I or love.
Example 2
Input: s = "an at in"
Output: "an"
Explanation: All three have 2 letters; the first of them, an, is the answer.
Example 3
Input: s = " hello "
Output: "hello"
Explanation: The spaces around it don't belong to the word.
Example 4
Input: s = "a bb ccc dd"
Output: "ccc"
Explanation: ccc, with 3 characters, is the longest.
Constraints
- 1 ≤ s.length ≤ 10^5
sconsists of English letters, digits, punctuation and spaces (' ')shas at least one word
Editorial
Approach - Measure Each Word as It Ends
Intuition
A word ends at the first space after it, or at the end of the string. When one ends, compare its length with the best so far, and keep it only if it's strictly longer: then of several equally long words the first one stays, as the problem asks.
Don't forget the last word: often no space comes after it, so the end of the string has to end a word too.
Step-by-Step Explanation
Let's trace Example 2, s = "an at in":
an, 2 characters: longer than anything before, so it's the best.at, 2 characters: not longer thanan, soanstays.in, 2 characters: not longer thanan, soanstays.- Return
"an".
The First Longest Word — The best word so far in green; a word that's only as long, in amber, doesn't replace it.
Algorithm
- Keep the best word, empty at first, and where the current word started.
- At each space, and once more at the end of the string: if a word just ended and it's longer than the best, it becomes the best.
- Return the best.
Code
class Solution {
public:
string longestWord(string& s) {
string best;
int start = -1, n = s.size();
for (int i = 0; i <= n; i++) {
if (i < n && s[i] != ' ') {
if (start < 0) start = i; // a word begins
} else if (start >= 0) { // a word just ended, at a space or the end
if (i - start > (int) best.size()) best = s.substr(start, i - start);
start = -1;
}
}
return best;
}
};
class Solution:
def longestWord(self, s: str) -> str:
best, start = "", -1
for i in range(len(s) + 1):
if i < len(s) and s[i] != " ":
if start < 0:
start = i # a word begins
elif start >= 0: # a word just ended, at a space or the end
if i - start > len(best):
best = s[start:i]
start = -1
return best
class Solution {
public String longestWord(String s) {
String best = "";
int start = -1;
for (int i = 0; i <= s.length(); i++) {
if (i < s.length() && s.charAt(i) != ' ') {
if (start < 0) start = i; // a word begins
} else if (start >= 0) { // a word just ended, at a space or the end
if (i - start > best.length()) best = s.substring(start, i);
start = -1;
}
}
return best;
}
}
var longestWord = function(s) {
let best = "", start = -1;
for (let i = 0; i <= s.length; i++) {
if (i < s.length && s[i] !== " ") {
if (start < 0) start = i; // a word begins
} else if (start >= 0) { // a word just ended, at a space or the end
if (i - start > best.length) best = s.slice(start, i);
start = -1;
}
}
return best;
};
Complexity Analysis
Time Complexity: O(n)
Each character is looked at once, and each word copied at most once when it's the best.
Space Complexity: O(n)
The best word.
Common Mistakes
Each of these looks right on a quick read, and the tests still reject it. The outputs below come from running the code.
Replacing the best on a tie. len(word) >= len(best)
On s = "an at in" it returns "in"; the answer is "an". With >=, a later word of the same length replaces the best, so a tie gives the last of the longest words. Only a strictly longer word should replace it.
Only measuring a word at a space. for i in range(len(s)):
On s = "I love programming" it returns "love"; the answer is "programming". Measuring each word when a space ends it misses the last word if no space comes after it, and that may be the longest. The end of the string ends a word too.
Taking the space after the word. s[start:i + 1]
On s = "an at in" it returns "an "; the answer is "an". The word runs from its first character up to, not including, the space that ends it. Slicing to i + 1 takes that space along.
Where This Pattern Is Taught
This problem practises finding where each word starts and ends in one pass. It's taught in Introduction to Strings.