「这是我参与11月更文挑战的第二天,活动详情查看:2021最后一次更文挑战」
各位小伙伴大家好啊,今天是第三天了。加油💪!!!
第一题 剑指 Offer 05. 替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = "We are happy."
输出:"We%20are%20happy."
限制:
0 <= s 的长度 <= 10000
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ti…
解题思路:
阅读题目后,可以很快速的想到JavaScript字符串中的replace方法,那么就A了。
这样做虽然没有什么问题,日常开发中多半也是如此实现的,但面试的时候,这多半不是一个满意的答案。看了一下其他人的做法,利用双指针来替换字符串:这在c++中是很好的方法。而由于JavaScript中字符串是不可变的,那么双指针法的空间复杂度达不到C++中的O(1),只能是O(n)。因为要先将字符串存储在数组里。所以,在JavaScript中,创建一个新的字符串,赋值之后再返回的解法和该解法的空间复杂度一致,并且创建新字符串还只需要遍历原字符串一次就完成。双指针法还需要遍历两次(第一次计算变化后的长度,第二次从后向前赋值);
代码实现:
// 解法一
var replaceSpace = function(s) {
return s.replace(/\s/g, "%20");
};
// 解法二
var replaceSpace = function(s) {
let strArr = s.split("");
let preLength = strArr.length;
// 计算替换后的长度
let nowLength = preLength;
for(let item of strArr) {
if (item === ' ') {
nowLength += 2;
}
}
// 如果遇到空格则添加%20,否则赋原始值。
while (preLength >= 0) {
if (strArr[preLength] === ' ') {
strArr[nowLength--] = 0;
strArr[nowLength--] = 2;
strArr[nowLength] = '%';
} else {
strArr[nowLength] = strArr[preLength];
}
preLength--;
nowLength--;
}
return strArr.join('');
};
注意:为什么是从后往前遍历数组? 因为从前往后遍历的话需要将后面的值依次向后移动,会增加时间复杂度,从后向前则不需要。
第二题 剑指 Offer 58 - II. 左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例 1:
输入: s = "abcdefg", n = 2
输出: "cdefgab"
示例 2:
输入: s = "lrloseumgh", n = 6
输出: "umghlrlose"
限制:
1 <= k < s.length <= 10000
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/zu…
解题思路:看到这里,如果对JavaScript的字符串方法熟悉的话,很容易想到slice,substr,substring方法。先取前一部分字符串和后一部分字符串,再用后一部分字符串拼接前一部分字符串。那么该题就过了。
关于三者的区别:js substr,slice,substring 的用法与区别
接下来,我们看看有没有其他的方法。看了一下题解,发现大多数方法都差不多,但是有一个方法很巧妙,局部反转+整体反转。先反转子串,从开始到n,再反转n到结尾,最后反转整个字符串,就达到了题目的效果。这里给出实现。
代码实现:
// 方法一
var reverseLeftWords = function(s, n) {
return s.slice(n) + s.slice(0, n);
};
// 方法二
var reverseLeftWords = function(s, n) {
let strArr = s.split('');
reverse(strArr, 0, n-1);
reverse(strArr, n, strArr.length-1);
reverse(strArr, 0, strArr.length-1);
return strArr.join('');
};
var reverse = function(strArr, start, end) {
// 双指针反转
while(start < end) {
let temp = strArr[start];
strArr[start] = strArr[end];
strArr[end] = temp;
start++;
end--;
}
}
总结
今天的题都是简单题,但从中也看到了许多有趣的解法。写程序就是这样,解决问题的方法很多,有的方法是十分巧妙的,只有多思考,多学习,才能想出这样的方法。如果有什么不对的地方,或者有更好的方案,欢迎提出,大家一起讨论。