344. 反转字符串
双指针法:一个从最前一个从最后相互交换数值,js中可以使用解构赋值来交换。
/**
* @param {character[]} s
* @return {void} Do not return anything, modify s in-place instead.
*/
var reverseString = function(s) {
let left = 0, right = s.length - 1;
while(left < right){
[s[left], s[right]] = [s[right], s[left]];
left++;
right--;
}
};
541. 反转字符串II
本题反转字符串的循环的区间是2 * k,所以在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
/**
* @param {string} s
* @param {number} k
* @return {string}
*/
var reverseStr = function (s, k) {
let arr = s.split('');
const len = s.length;
for (let i = 0; i < len; i += 2 * k) {
let left = i - 1, right = i + k > len ? len : i + k;
while (++left < --right) {
[arr[left], arr[right]] = [arr[right], arr[left]];
}
}
return arr.join('');
};
剑指offer05. 替换空格
首先扩充数组到每个空格替换成"%20"之后的大小。然后从后向前替换空格,也就是双指针法,i指向新长度的末尾,j指向旧长度的末尾。
/**
* @param {string} s
* @return {string}
*/
var replaceSpace = function (s) {
let strArr = Array.from(s);
let count = 0;
// 计算空格数量
for (let i = 0; i < strArr.length; i++) {
if (strArr[i] === ' ') {
count++;
}
}
let left = strArr.length - 1;
let right = strArr.length + count * 2 - 1;
while(left >= 0){
if(strArr[left] === ' '){
strArr[right--] = '0';
strArr[right--] = '2';
strArr[right--] = '%';
left--;
}
else {
strArr[right--] = strArr[left--];
}
}
return strArr.join('');
};
151. 反转字符串中的单词
- 移除多余空格:用双指针法来移除空格,fast指针先遍历字符串来寻找指针,slow指针指向字符串从0开始的被替换的位置。
注意:需要判断前导空格、单词间的多个空格(如果有多个只保留一个,如果当前位置的前一个是空格就把当前位置的删了)、尾随空格(如果遍历到最后新数组的最后一个元素是空格,那么就把数组的length缩短一下)。 - 反转整个字符串
- 反转单个单词:如果遇到空格或者遍历到最后一个位置了,那么就反转前一个单词了。
/**
* @param {string} s
* @return {string}
*/
// 翻转从 start 到 end 的字符
function reverse(strArr, start, end) {
let left = start;
let right = end;
while(left < right) {
// 交换
[strArr[left], strArr[right]] = [strArr[right], strArr[left]];
left++;
right--;
}
}
// 删除多余空格
function removeExtraSpaces(strArr){
let slowIndex = 0, fastIndex = 0;
while(fastIndex < strArr.length) {
// 移除开始位置和重复的空格
if(strArr[fastIndex] === ' ' && (fastIndex === 0 || strArr[fastIndex - 1] === ' ')){
fastIndex++;
} else {
strArr[slowIndex++] = strArr[fastIndex++];
}
}
// 移除末尾空格
strArr.length = strArr[slowIndex - 1] === ' ' ? slowIndex - 1 : slowIndex;
}
var reverseWords = function(s) {
let strArr = Array.from(s);
// 移除多余空格
removeExtraSpaces(strArr);
// 翻转
reverse(strArr, 0, strArr.length - 1);
let start = 0;
for(let i = 0; i <= strArr.length; i++) {
if (strArr[i] === ' ' || i === strArr.length) {
// 翻转单词
reverse(strArr, start, i - 1);
start = i + 1;
}
}
return strArr.join('');
};
剑指offer58.左旋字符串
具体步骤为:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
/**
* @param {string} s
* @param {number} n
* @return {string}
*/
function reverse(strArr, start, end) {
let left = start, right = end;
while(left < right) {
[strArr[left], strArr[right]] = [strArr[right], strArr[left]];
left++;
right--;
}
}
var reverseLeftWords = function (s, n) {
let strArr = Array.from(s);
const len = strArr.length;
reverse(strArr, 0, len - 1);
reverse(strArr, 0, len - n - 1);
reverse(strArr, len - n, len - 1);
return strArr.join('');
};