返回

洞悉先机,破译算法奥秘:十道必刷前端算法题全解析(二)

前端

前言

在前端开发领域,算法能力是衡量程序员综合素质的重要标准之一。算法题是面试中常见的考察内容,也是前端开发工程师在实际工作中经常会遇到的难题。掌握扎实的算法功底,不仅可以帮助您轻松应对面试挑战,更能提升您解决复杂问题的能力,在职业发展中取得更大的成就。

十道精选前端算法题

为了帮助您系统地掌握算法知识,我们精心挑选了十道精选算法题,涵盖各种经典算法思想和数据结构,包括数组、链表、栈、队列、树、图等。每道题都附有详细的解析和代码示例,让您轻松理解算法精髓,掌握解决问题的关键技巧。

算法题解析

1. 两数之和

给定一个整数数组和一个目标值,找出数组中两个数的索引,使得它们的和等于目标值。

const twoSum = (nums, target) => {
  const map = new Map();
  for (let i = 0; i < nums.length; i++) {
    const complement = target - nums[i];
    if (map.has(complement)) {
      return [map.get(complement), i];
    }
    map.set(nums[i], i);
  }
  return null;
};

2. 无重复字符的最长子串

给定一个字符串,找出不包含重复字符的最长子串的长度。

const lengthOfLongestSubstring = (str) => {
  let start = 0;
  let end = 0;
  let maxLength = 0;
  const set = new Set();
  while (end < str.length) {
    if (!set.has(str[end])) {
      set.add(str[end]);
      maxLength = Math.max(maxLength, end - start + 1);
      end++;
    } else {
      set.delete(str[start]);
      start++;
    }
  }
  return maxLength;
};

3. 最长公共子序列

给定两个字符串,找出它们的公共子序列中最长字符串的长度。

const longestCommonSubsequence = (str1, str2) => {
  const dp = Array(str1.length + 1).fill(0).map(() => Array(str2.length + 1).fill(0));
  for (let i = 1; i <= str1.length; i++) {
    for (let j = 1; j <= str2.length; j++) {
      if (str1[i - 1] === str2[j - 1]) {
        dp[i][j] = dp[i - 1][j - 1] + 1;
      } else {
        dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
      }
    }
  }
  return dp[str1.length][str2.length];
};

4. 最长回文子串

给定一个字符串,找出它的最长回文子串。

const longestPalindrome = (str) => {
  let start = 0;
  let end = 0;
  let maxLength = 0;
  for (let i = 0; i < str.length; i++) {
    const oddLength = expandAroundCenter(str, i, i);
    const evenLength = expandAroundCenter(str, i, i + 1);
    const currentLength = Math.max(oddLength, evenLength);
    if (currentLength > maxLength) {
      start = i - Math.floor((currentLength - 1) / 2);
      end = i + Math.floor(currentLength / 2);
      maxLength = currentLength;
    }
  }
  return str.substring(start, end + 1);

  function expandAroundCenter(str, left, right) {
    while (left >= 0 && right < str.length && str[left] === str[right]) {
      left--;
      right++;
    }
    return right - left - 1;
  }
};

5. 容器盛最多水的面积

给定一个非负整数数组,代表一个容器的形状,找出该容器能盛最多水的面积。

const maxArea = (heights) => {
  let maxArea = 0;
  let left = 0;
  let right = heights.length - 1;
  while (left < right) {
    const currentArea = Math.min(heights[left], heights[right]) * (right - left);
    maxArea = Math.max(maxArea, currentArea);
    if (heights[left] < heights[right]) {
      left++;
    } else {
      right--;
    }
  }
  return maxArea;
};

6. 三数之和

给定一个整数数组和一个目标值,找出数组中三个数的索引,使得它们的和等于目标值。

const threeSum = (nums, target) => {
  nums.sort((a, b) => a - b);
  const result = [];
  for (let i = 0; i < nums.length - 2; i++) {
    if (i > 0 && nums[i] === nums[i - 1]) {
      continue;
    }
    let left = i + 1;
    let right = nums.length - 1;
    while (left < right) {
      const sum = nums[i] + nums[left] + nums[right];
      if (sum === target) {
        result.push([nums[i], nums[left], nums[right]]);
        while (left < right && nums[left] === nums[left + 1]) {
          left++;
        }
        while (left < right && nums[right] === nums[right - 1]) {
          right--;
        }
        left++;
        right--;
      } else if (sum < target) {
        left++;
      } else {
        right--;
      }
    }
  }
  return result;
};

7. 旋转数组中的最小数字

给定一个有序数组,该数组可能包含重复的元素,并被旋转过多次,找到数组中的最小数字。

const findMin = (nums) => {
  let left = 0;
  let right = nums.length - 1;
  while (left < right) {
    const mid = Math.floor((left + right) / 2);
    if (nums[mid] > nums[right]) {
      left = mid + 1;
    } else if (nums[mid] < nums[right]) {
      right = mid;
    } else {
      right--;
    }
  }
  return nums[left];
};

8. 搜索旋转排序数组

给定一个有序数组,该数组可能包含重复的元素,并被旋转过多次,找到数组中目标值的索引,如果目标值不存在,则返回 -1。

const search = (nums, target) => {
  let left = 0;
  let right = nums.length - 1;
  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (nums[mid] === target) {
      return mid;
    }
    if (nums[left] <= nums[mid]) {
      if (target >= nums[left] && target < nums[mid]) {
        right = mid - 1;
      } else {
        left = mid + 1;
      }
    } else {
      if (target > nums[mid] && target <= nums[right]) {
        left = mid + 1;
      } else {
        right = mid - 1;
      }
    }
  }
  return -1;
};

9. 合并两个有序数组

给定两个有序数组,将它们合并为一个新的有序数组。

const merge = (