返回

完美剖析[路飞]_js算法实现:名师带你精通前 K 个高频元素、二叉树的直径、最长回文串、最长递增子序列、排序数组

前端

前 K 个高频元素

前 K 个高频元素问题是数据结构与算法中经典的问题之一。给定一个整数数组和一个整数 k,要求找出其中出现频率前 k 高的元素。

思路:

  • 桶排序:我们可以将数组中的元素作为桶的索引,并将每个元素出现的次数作为桶中的值。然后,我们将桶中的值从大到小排序,并取前 k 个元素即可。
function topKFrequent(nums, k) {
  const map = new Map();
  for (const num of nums) {
    map.set(num, (map.get(num) || 0) + 1);
  }

  const buckets = new Array(nums.length + 1).fill(0);
  for (const [num, count] of map) {
    buckets[count]++;
  }

  const result = [];
  for (let i = nums.length; i >= 0; i--) {
    while (buckets[i] > 0) {
      result.push(num);
      buckets[i]--;
    }

    if (result.length === k) {
      return result;
    }
  }

  return result;
}

二叉树的直径

二叉树的直径问题也是一个经典问题,它是指二叉树中最长路径的长度。

思路:

  • 深度优先搜索:我们可以使用深度优先搜索来求解二叉树的直径。对于每个结点,我们计算其左右子树的深度,然后将两者相加再加 1,即可得到以该结点为根的路径的长度。最后,我们取所有结点中路径长度最大的那个,即为二叉树的直径。
function diameterOfBinaryTree(root) {
  let diameter = 0;

  function depth(node) {
    if (!node) {
      return 0;
    }

    const left = depth(node.left);
    const right = depth(node.right);

    diameter = Math.max(diameter, left + right + 1);

    return Math.max(left, right) + 1;
  }

  depth(root);

  return diameter;
}

最长回文串

最长回文串问题是字符串处理中常见的问题之一,它是指给定一个字符串,要求找出其中最长的回文子串。

思路:

  • 动态规划:我们可以使用动态规划来求解最长回文串问题。首先,我们将字符串中的每个字符作为一个子问题,并计算每个子问题的最长回文子串。然后,我们将相邻子问题的最长回文子串合并起来,即可得到整个字符串的最长回文子串。
function longestPalindrome(str) {
  const n = str.length;
  const dp = new Array(n).fill(false);

  let start = 0;
  let end = 0;
  let maxLen = 1;

  for (let i = 0; i < n; i++) {
    dp[i][i] = true;

    for (let j = i - 1; j >= 0; j--) {
      if (str[j] === str[i] && (i - j <= 2 || dp[j + 1][i - 1])) {
        dp[j][i] = true;

        if (i - j + 1 > maxLen) {
          start = j;
          end = i;
          maxLen = i - j + 1;
        }
      }
    }
  }

  return str.substring(start, end + 1);
}

最长递增子序列

最长递增子序列问题是动态规划中的经典问题之一,它是指给定一个整数数组,要求找出其中最长的递增子序列。

思路:

  • 动态规划:我们可以使用动态规划来求解最长递增子序列问题。首先,我们将数组中的每个元素作为一个子问题,并计算每个子问题的最长递增子序列。然后,我们将相邻子问题的最长递增子序列合并起来,即可得到整个数组的最长递增子序列。
function longestIncreasingSubsequence(nums) {
  const n = nums.length;
  const dp = new Array(n).fill(1);

  let maxLen = 1;

  for (let i = 1; i < n; i++) {
    for (let j = 0; j < i; j++) {
      if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
        dp[i] = dp[j] + 1;
      }
    }

    maxLen = Math.max(maxLen, dp[i]);
  }

  return maxLen;
}

排序数组

排序数组问题是计算机科学中的基础问题之一,它是指给定一个整数数组,要求将其从小到大排序。

思路:

  • 快速排序:我们可以使用快速排序来排序数组。快速排序的思想是:将数组分成两部分,一部分包含比基准元素小的元素,另一部分包含比基准元素大的元素。然后,我们将这两部分分别排序,最后合并起来即可。
function quickSort(nums) {
  if (nums.length <= 1) {
    return nums;
  }

  const pivot = nums[0];
  const left = [];
  const right = [];

  for (let i = 1; i < nums.length; i++) {
    if (nums[i] < pivot) {
      left.push(nums[i]);
    } else {
      right.push(nums[i]);
    }
  }

  return quickSort(left).concat(pivot, quickSort(right));
}

以上便是对由[路飞]在JavaScript中实现的前 K 个高频元素、二叉树的直径、最长回文串、最长递增子序列、排序数组等算法的深入解析。希望这篇