比较常规的一道题,思路见:反转字符串
// javascript
var reverseString = function(s) {
const n = s.length;
for (let i = 0, j = n - 1; i < j; ++i, --j) {
[s[i], s[j]] = [s[j], s[i]];
}
};
因为在 js 中字符串是不可变的,所以要转换成矩阵来操作。
反转每个下标从 2 k 2k 2k 的倍数开始的,长度为 k k k 的子串。若该子串长度不足 k k k,则反转整个子串。
// javascript
var reverseStr = function(s, k) {
const n = s.length;
const arr = Array.from(s);
for (let i = 0; i < n; i += (2 * k)) {
let left = i, right = Math.min(i + k, n) - 1;
while (left < right) {
[arr[left], arr[right]] = [arr[right], arr[left]];
left++;
right--;
}
}
return arr.join('');
};
因为在 js 中字符串是不可变的,所以要转换成矩阵来操作。arr 按空格来分割,每个单词又按字母分割。一个单词一个单词的反转,最后先把一个单词和起来,再把所有单词用空格连接。
s: "Let's take LeetCode contest"
arr: [['L', 'e', 't', "'", 's'], ['t', 'a', 'k', 'e'], ['L', 'e', 'e', 't', 'C', 'o', 'd', 'e'], ['c', 'o', 'n', 't', 'e', 's', 't']]
// javascript
var reverseWords = function(s) {
// 前一个是空格,后一个是空字符串
const arr = s.split(' ').map(v => v.split(''));
for (let i = 0; i < arr.length; ++i) {
for (let l = 0, r = arr[i].length - 1; l < r; ++l, --r) {
[arr[i][l], arr[i][r]] = [arr[i][r], arr[i][l]];
}
}
// 前一个是空字符串,后一个是空格
return arr.map(v => v.join('')).join(' ');
};
也可以一步一步地去写:
开辟一个新字符串。然后从头到尾遍历原字符串,直到找到空格为止,此时找到了一个单词,并能得到单词的起止位置。随后,根据单词的起止位置,可以将该单词逆序放到新字符串当中。如此循环多次,直到遍历完原字符串,就能得到翻转后的结果。
// javascript
var reverseWords = function(s) {
const n = s.length;
const res = new Array();
let i = 0;
while (i < n) {
let start = i;
while (i < n && s[i] !== ' ') i++;
for (let j = i - 1; j >= start; --j) {
res.push(s[j]);
}
if (i < n && s[i] === ' ') { // 注意这一步
res.push(' ');
i++;
}
}
return res.join('');
};
// javascript
var reverseWords = function(s) {
const n = s.length;
const res = new Array();
let i = 0;
while (i < n) {
let start = i;
while (i < n && s[i] !== ' ') {
res.push(s[i]);
i++;
}
for (let left = start, right = i - 1; left < right; ++left, --right) {
[res[left], res[right]] = [res[right], res[left]];
}
if (i < n && s[i] === ' ') {
res.push(' ');
i++;
}
}
return res.join('');
};