持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情
题目
给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入:s = "Let's take LeetCode contest"
输出:"s'teL ekat edoCteeL tsetnoc"
示例 2:
输入: s = "God Ding"
输出:"doG gniD"
提示:
1 <= s.length <= 5 * 10^4s包含可打印的 ASCII 字符。s不包含任何开头或结尾空格。s里 至少 有一个词。s中的所有单词都用一个空格隔开。
思考
本题难度简单。
首先是读懂题意。 给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。可以注意到s 不包含任何开头或结尾空格,且s 中的所有单词都用一个空格隔开。
我们可以通过一行代码就解决该问题,也就是将句子拆分为单词,然后逐个单词翻转并连接起来。js 代码有时候显得很精炼!
我们也可以使用双指针的方法。定义 l 和 r 两个指针,表示单词的左右边界。遍历字符串 s,当碰到空格时,更新 r 为 i - 1,同时倒序遍历单词,最后添加当前空格,并更新 l 为 i + 1。当遍历到最后一个字符时,满足l < s.length,倒序添加该单词即可。
解答
方法一:一行代码解决
/**
* @param {string} s
* @return {string}
*/
var reverseWords = function(s) {
return s.split(' ').map(str => [...str].reverse().join('')).join(' ')
}
// 执行用时:92 ms, 在所有 JavaScript 提交中击败了10.58%的用户
// 内存消耗:47.1 MB, 在所有 JavaScript 提交中击败了71.95%的用户
// 通过测试用例:29 / 29
复杂度分析:
- 时间复杂度:O(n),其中 n 为字符串 s 的长度。
- 空间复杂度:O(1)。
方法二:双指针
/**
* @param {string} s
* @return {string}
*/
var reverseWords = function(s) {
let l = 0, r = 0, ans = ''
for (let i = 0; i < s.length; i++) {
if (s[i] === ' ') {
r = i - 1
let rr = r
while (rr >= l) {
ans += s[rr]
rr--
}
ans += ' '
l = i + 1
// console.log(s.length, l, r)
}
}
if (l < s.length) {
rr = s.length - 1
while (rr >= l) {
ans += s[rr]
rr--
}
}
return ans
}
// 执行用时:80 ms, 在所有 JavaScript 提交中击败了34.94%的用户
// 内存消耗:47.1 MB, 在所有 JavaScript 提交中击败了64.18%的用户
// 通过测试用例:29 / 29
复杂度分析:
- 时间复杂度:O(n),其中 n 为字符串 s 的长度。
- 空间复杂度:O(1)。