学习时间:
- 晚上 7 点—晚上9点
344.反转字符串:
建议: 本题是字符串基础题目,就是考察 reverse 函数的实现,同时也明确一下 平时刷题什么时候用 库函数,什么时候 不用库函数
思路:
反转字符串依然是使用双指针的方法,只不过对于字符串的反转,其实要比链表简单一些。
因为字符串也是一种数组,所以元素在内存中是连续分布,这就决定了反转链表和反转字符串方式上还是有所差异的。
代码实现:
var reverseString = function (char) {
let charLen = Math.floor(char.length / 2)
for (let i = 0, j = char.length - 1; i < charLen; i++, j--) {
tempStr = char[i];
char[i] = char[j];
char[j] = tempStr;
}
return char
}
541. 反转字符串II
思路:
其实在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
因为要找的也就是每2 * k 区间的起点,这样写,程序会高效很多。
所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。
代码实现:
var reverse = function (char, start, end) {
for (let i = start, j = end; i < j; i++, j--) {
console.log(char[i], char[j])
tempStr = char[i];
char[i] = char[j];
char[j] = tempStr;
}
return char
}
var reverseStr = function (s, k) {
let resArr = s.split("");
for (let i = 0; i < s.length; i += (2 * k)) {
let l = i, r = i + k - 1 > s.length ? s.length : i + k - 1
console.log(r, '==')
reverse(resArr, l, r)
// console.log(resArr)
}
return resArr.join("");
}
剑指Offer 05.替换空格
思路:
如果想把这道题目做到极致,就不要只用额外的辅助空间了!
首先扩充数组到每个空格替换成"%20"之后的大小。
然后从后向前替换空格,也就是双指针法,过程如下:
i指向新长度的末尾,j指向旧长度的末尾。
代码实现:
var replaceSpace = function (s) {
const strArr = Array.from(s)
let count = 0
for (let i = 0; i < s.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.翻转字符串里的单词
思路:
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
代码实现:
//先将字符串转换成字符串数组 然后清掉多余空格 再将整个数组转过来 然后再进行每个单词的翻转
var reverseWords = function (s) {
const strArr = Array.from(s)
console.log(strArr.length)
let slow = 0;
removeExtraSpace(strArr)
reverse(strArr, 0, strArr.length - 1)
console.log(strArr)
let start = 0
for (let fast = 0; fast <= strArr.length; fast++) {
//如果碰到空格了或者fast的长度到达最长的时候就进行翻转单词
if (strArr[fast] === ' ' || fast === strArr.length) {
reverse(strArr, start, fast - 1)
console.log(strArr, fast)
//翻转成功后 start从fast的下一位开始
start = fast + 1
}
}
return strArr.join('');
};
console.log(reverseWords('the sky is blue'))
function removeExtraSpace (strArr) {
let slowIndex = 0;
let 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
}
function reverse (strArr, start, end) {
let left = start
let right = end
while (left < right) {
[strArr[left], strArr[right]] = [strArr[right], strArr[left]]
left++
right--
}
}
剑指Offer58-II.左旋转字符串
思路:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
代码实现:
var reverseLeftWords = function (s, n) {
let strArr = Array.from(s)
let strLen = strArr.length
reverse(strArr, 0, n - 1)
reverse(strArr, n, strLen)
reverse(strArr, 0, strLen)
return strArr.join('')
};
console.log(reverseLeftWords("abcdefg", 2))
function reverse (strArr, start, end) {
let left = start
let right = end
while (left < right) {
[strArr[left], strArr[right]] = [strArr[right], strArr[left]]
left++
right--
}
}
总结
第一次接触完全想不到这么多办法,看来这方面的题必须要多次复习, 希望早日形成自己的题感