这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战
翻转单词顺序
剑指Offer 58 - I. 翻转单词顺序
难度:简单
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串“I am a student.”,则输出 “student. a am I”。
示例1:
输入: "the sky is blue"
输出: "blue is sky the"
示例2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例3:
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
- 无空格字符构成一个单词。
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
- 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
题解
法一 使用API
- trim()删除字符串两端空格
- split(' ')切割空格变为数组
- filter()过滤数组中的空格
- reverse()反转数组
- join(' ')以空格为界限,数组转字符串
/**
* @param {string} s
* @return {string}
*/
var reverseWords = function (s) {
let str = s.trim().split(' ').filter(item => item != '').reverse().join(' ');
return str;
};
- 时间复杂度:O(N)
- 空间复杂度:O(N)
法二 双指针
步骤:
- 去掉首尾空格,从后往前遍历字符串s,记录左右索引边界i和j
- 每确定一个单词的边界,则将单词放入数组res
- 数组res转字符串后返回
var reverseWords = function (s) {
// 1.去掉首尾空格
s = s.trim();
let j = s.length - 1,
i = j;
let res = [];
while (j >= 0) {
while (i >= 0 && s[i] !== ' ') i--;// 搜索空格
res.push(s.slice(i + 1, j + 1)); // 添加单词
while (j >= 0 && s[i] === ' ') i--; // 跳过空格
j = i; // j指向下一个单词
}
return res.join(' '); // 数组转字符串
};
- 时间复杂度:O(N)
- 空间复杂度:O(N)
左旋转字符串
剑指Offer 58 - II. 左旋转字符串
难度:简单
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串“abcdefg”和数字2,该函数将返回左旋转两位得到的结果“cdefgab”。
示例1:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
实例2:
输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
限制:1 <= k < s.length <= 10000
题解
法一 字符串拼接
/**
* @param {string} s
* @param {number} n
* @return {string}
*/
var reverseLeftWords = function (s, n) {
let str = s.substring(n) + s.substring(0, n);
return str;
};
- 时间复杂度:O(N)
- 空间复杂度O(N)
法二 列表遍历拼接
若面试中不允许使用API,则可以使用这种方法。步骤如下:
- 新建数组res
- 将n+1后的值存入res
- 再向res存入首位至n位的字符
- 数组res转字符串
var reverseLeftWords = function (s, n) {
const res = [];
for (let i = n; i < s.length; i++) {
res.push(s[i]);
}
for (let i = 0; i < n; i++) {
res.push(s[i]);
}
return res.join('');
};
- 时间复杂度:O(N)
- 空间复杂度:O(N)
坚持每日一练!前端小萌新一枚,希望能点个赞哇~