《手写代码》前端面试题

js限制并发数量

const limitedRequest = (requestList, maxConcurrency) => {
    // 运行池
    const pool = new Set();
  
    // 等待队列
    const waitQueue = [];
  
    // 结果数组,用于收集每个请求的结果
    const results = [];
  
    // 执行单个请求的函数
    const executeRequest = (reqFn) => {
      return new Promise((resolve, reject) => {
        reqFn()
          .then(res => {
            results.push(res); // 将请求结果存入结果数组
            resolve(res);
          })
          .catch(err => reject(err))
          .finally(() => {
            // 请求完成后,从运行池中删除该请求
            pool.delete(reqFn);
            // 尝试从等待队列中取出下一个请求执行
            const next = waitQueue.shift();
            if (next) {
              pool.add(next);
              next();
            }
          });
      });
    };
  
    // 对每个请求进行处理
    const requestPromises = requestList.map(async (reqFn) => {
      // 包装请求函数,加入到等待队列或运行池中
      const wrappedReqFn = () => executeRequest(reqFn);
  
      // 判断运行池是否已满
      const isFull = pool.size >= maxConcurrency;
  
      if (isFull) {
        // 如果运行池已满,则将请求放入等待队列
        waitQueue.push(wrappedReqFn);
      } else {
        // 如果运行池未满,则直接加入运行池并执行该请求
        pool.add(wrappedReqFn);
        wrappedReqFn();
      }
    });
  
    // 等待所有请求执行完毕,然后返回结果数组
    return Promise.all(requestPromises)
      .then(() => results); // 返回执行完成后的结果数组
  }; 

输入一个字符串,遇到方括号则对方括号内的字符串重复n次,n是方括号前面的数字(1 <= n <= 100),如果没有数字则为1次,可能存在嵌套 const str1 = 'a2[b]a2[b2[c]]' // abbabccbcc const str2 = '2[3[c]]a2a' // cccccca2a const str3 = '[abc][d]3[e2]4' // abcde2e2e24

function decodeString(s) {
    let stack = []; // 用于存储解码过程中的字符和数字
    let currentNum = 0; // 当前数字,用于记录重复次数
    let currentStr = ''; // 当前字符串,用于构建解码后的结果

    for (let char of s) {
        if (char >= '0' && char <= '9') {
            // 如果是数字字符,更新当前数字
            currentNum = currentNum * 10 + parseInt(char, 10);
        } else if (char === '[') {
            // 如果是 '[',将当前字符串和当前数字入栈,并重置当前字符串和当前数字
            stack.push(currentStr);
            stack.push(currentNum);
            currentStr = '';
            currentNum = 0;
        } else if (char === ']') {
            // 如果是 ']',则进行解码操作
            let num = stack.pop(); // 弹出之前存储的重复次数
            let prevStr = stack.pop(); // 弹出之前存储的字符串
            currentStr = prevStr + currentStr.repeat(num); // 构建解码后的字符串
        } else {
            // 如果是普通字符,直接加入当前字符串
            currentStr += char;
        }
    }

    return currentStr; // 返回最终解码后的字符串
}

const str1 = 'a2[b]a2[b2[c]]'; // abbabccbcc
const str2 = '2[3[c]]a2a'; // cccccca2a
const str3 = '[abc][d]3[e2]4'; // abcde2e2e24

console.log(decodeString(str1)); // 输出:abbabccbcc
console.log(decodeString(str2)); // 输出:ccccccca2a
console.log(decodeString(str3)); // 输出:abcde2e2e24
  • stack 栈用于辅助解码过程,存储了解码过程中的字符串和重复次数。
  • currentNum 用于记录当前的重复次数,当遇到数字字符时更新。
  • currentStr 用于构建当前的字符串,当遇到普通字符时追加到 currentStr
  • 在遇到 [ 时,将 currentStr 和 currentNum 压入栈中,同时重置它们。
  • 在遇到 ] 时,从栈中弹出之前存储的 prevStr 和 num,将 currentStr 重复 num 次后拼接到 prevStr 上,得到解码后的结果。
  • 最终返回 currentStr,即为解码后的字符串。

js实现 ['a', 'b', 'c', 'd'] => {a: {b: {c: {d: null}}}}

function arrayToNestedObject(arr) {
  return arr.reduceRight((acc, curr) => {
    return {[curr]: acc};
  }, null);
}

const result = arrayToNestedObject(['a', 'b', 'c', 'd']);
console.log(result); // 输出 { a: { b: { c: { d: null } } } }

使用了 reduceRight 方法来从数组中的最后一个元素开始,逐步向内层嵌套构建对象,最终得到了您想要的嵌套对象结构。

寻找最长无重复子串长度

function longestSubstring(s) {
  const n = s.length;
  let maxLength = 0;
  let left = 0;
  const charSet = new Set();

  for (let right = 0; right < n; right++) {
    const currentChar = s[right];

    // 如果当前字符在集合中,移动左边界直到没有重复字符
    while (charSet.has(currentChar)) {
      charSet.delete(s[left]);
      left++;
    }

    // 将当前字符加入集合
    charSet.add(currentChar);

    // 更新最长无重复子串的长度
    maxLength = Math.max(maxLength, right - left + 1);
  }

  return maxLength;
}

寻找最长无重复子串

function longestSubstring(s) {
  const n = s.length;
  let maxLength = 0;
  let left = 0;
  let result = '';
  const charSet = new Set();

  for (let right = 0; right < n; right++) {
    const currentChar = s[right];

    // 如果当前字符在集合中,移动左边界直到没有重复字符
    while (charSet.has(currentChar)) {
      charSet.delete(s[left]);
      left++;
    }

    // 将当前字符加入集合
    charSet.add(currentChar);

    // 更新最长无重复子串
    if (right - left + 1 > maxLength) {
      maxLength = right - left + 1;
      result = s.substring(left, right + 1);
    }
  }

  return result;
}

// 测试例子
console.log(longestSubstring("abcabcbb")); // 输出 "abc"
console.log(longestSubstring("bbbbb"));    // 输出 "b"
console.log(longestSubstring("pwwkew"));   // 输出 "wke"
console.log(longestSubstring(""));         // 输出 ""
console.log(longestSubstring("au"));       // 输出 "au"

计算x的n次方


function power(x, n) {
  // 处理负指数情况
  if (n < 0) {
    x = 1 / x;  // 将底数变为其倒数
    n = -n;     // 将指数变为其绝对值
  }
  
  let result = 1;  // 初始化结果为1,任何数的0次幂都是1

  // 计算幂的主循环
  while (n > 0) {
    if (n % 2 === 1) {  // 如果当前指数是奇数
      result *= x;      // 将当前底数乘到结果中
    }
    x *= x;             // 底数平方,相当于指数减半
    n = Math.floor(n / 2);  // 指数除以2,取整
  }

  return result;  // 返回最终结果
}
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值