思路
- 指针
- 递归
- 栈
指针
寻找字符串中最大连续重复的字符及次数
function findMaxRepeatChar(str) {
let maxCount = 0; // 定义最大重复次数
let maxChar = ''; // 定义最大重复次数的字符
let left = 0; // 定义左指针
let right = 0; // 定义右指针
while (right < str.length) { // 当右指针小于字符串长度时
if (str[right] !== str[left]) { // 如果右指针指向的字符与左指针指向的字符不同
if (right - left > maxCount) { // 如果右指针与左指针之间的距离大于最大重复次数
maxCount = right - left; // 更新最大重复次数
maxChar = str[left]; // 更新最大重复次数的字符
}
left = right; // 左指针指向右指针的位置
}
right++; // 右指针向右移动
}
if (right - left > maxCount) { // 如果右指针与左指针之间的距离大于最大重复次数
maxCount = right - left; // 更新最大重复次数
maxChar = str[left]; // 更新最大重复次数的字符
}
return { maxChar, maxCount }; // 返回最大重复次数的字符
}
递归
将高维数组 [1, 2, [3, [4, 5], 6], 7, [8], 9] 转换为以下对象
{
children: [
{ value: 1 },
{ value: 2 },
{
children: [
{ value: 3 },
{
children: [
{ value: 4 },
{ value: 5 }
]
},
{ value: 6 }
]
},
{ value: 7 },
{
children: [
{ value: 8 }
]
},
{ value: 9 }
]
}
function arrayToObject(arr) {
let obj = { children: [] };
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
obj.children.push(arrayToObject(arr[i]));
} else {
obj.children.push({ value: arr[i] });
}
}
return obj;
}
斐波那契数列 1 1 2 3 5 8 13 21 34 55
// 递归
function fibonacci(n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
// 缓存优化
function fibonacci(n, cache = {}) {
if (n in cache) {
return cache[n];
}
if (n <= 1) {
return n;
}
let result = fibonacci(n - 1, cache) + fibonacci(n - 2, cache);
cache[n] = result;
return result;
}
// 不用递归
function fibonacci(n) {
let dp = [0, 1];
for (let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
栈
编写“智能重复” smartRepeat 函数,实现
将 3[abc] 变为 abcabcabc
将 3[2[a]2[b]] 变成 aabbaabbaabb
将 2[1[a]3[b]2[3[c]4[d]]] 变成 abbbcccddddcccddddabbbcccddddcccdddd
function smartRepeat(templateStr) {
// 指针下标
let index = 0
// 栈一,存放数字
let stack1 = []
// 栈二,存放需要重复的字符串
let stack2 = []
let tailStr = templateStr
// 为啥遍历的次数为 length - 1 ? 因为要估计忽略最后的一个 ] 字符串
while (index < templateStr.length - 1) {
// 剩余没处理的字符串
tailStr = templateStr.substring(index)
if (/^\d+\[/.test(tailStr)) {
// 匹配 "[" 前的数字
let word = tailStr.match(/^(\d+)\[/)[1]
// 转为数字类型
let num = Number(word)
// 入栈
stack1.push(num)
stack2.push('')
index++
} else if (/^\w+\]/.test(tailStr)) {
// 匹配 "]" 前的需要重复的字符串
let word = tailStr.match(/^(\w+)\]/)[1]
// 修改栈二栈顶的字符串
stack2[stack2.length - 1] = word
// 让指针后移,word的长度,避免重复计算字符串
index += word.length
} else if (tailStr[0] === ']') {
// 遇到 [ 字符串就需要出栈了,栈一和栈二同时出栈,栈二出栈的字符串重复栈一出栈的 数字的次数,并赋值到栈二的新栈顶上
let times = stack1.pop()
let word = stack2.pop()
stack2[stack2.length - 1] += word.repeat(times)
index++
} else {
index++
}
}
// while结束之后, stack1 和 stack2 中肯定还剩余1项,若不是,则用户输入的格式错误
if (stack1.length !== 1 || stack2.length !== 1) {
throw new Error('输入的字符串有误,请检查')
} else {
return stack2[0].repeat(stack1[0])
}
}