当前位置:首页 > JavaScript

js实现查找逆序数

2026-01-31 06:12:53JavaScript

查找逆序数的实现方法

逆序数(Inversion Count)用于衡量一个数组或序列的排序程度。逆序数定义为数组中满足 i < jarr[i] > arr[j] 的元素对数。以下是几种常见的实现方法:

js实现查找逆序数

暴力法

直接遍历所有可能的元素对,统计逆序数。时间复杂度为 O(n²),适用于小规模数据。

js实现查找逆序数

function countInversionsBruteForce(arr) {
  let count = 0;
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] > arr[j]) count++;
    }
  }
  return count;
}

归并排序法

利用归并排序的分治思想,在合并过程中统计逆序数。时间复杂度为 O(n log n),适合大规模数据。

function countInversionsMergeSort(arr) {
  function mergeAndCount(arr, left, mid, right) {
    const temp = [];
    let i = left, j = mid + 1, count = 0;

    while (i <= mid && j <= right) {
      if (arr[i] <= arr[j]) {
        temp.push(arr[i++]);
      } else {
        temp.push(arr[j++]);
        count += mid - i + 1;
      }
    }

    while (i <= mid) temp.push(arr[i++]);
    while (j <= right) temp.push(arr[j++]);
    for (let k = left; k <= right; k++) arr[k] = temp[k - left];

    return count;
  }

  function mergeSortAndCount(arr, left, right) {
    let count = 0;
    if (left < right) {
      const mid = Math.floor((left + right) / 2);
      count += mergeSortAndCount(arr, left, mid);
      count += mergeSortAndCount(arr, mid + 1, right);
      count += mergeAndCount(arr, left, mid, right);
    }
    return count;
  }

  return mergeSortAndCount(arr, 0, arr.length - 1);
}

使用二叉索引树(Fenwick Tree)

通过动态维护前缀和的方式统计逆序数。时间复杂度为 O(n log n),但需要离散化数据。

function countInversionsFenwickTree(arr) {
  const unique = [...new Set(arr)].sort((a, b) => a - b);
  const rank = (x) => unique.indexOf(x) + 1;

  const fenwick = new Array(unique.length + 1).fill(0);
  function update(index, delta) {
    while (index < fenwick.length) {
      fenwick[index] += delta;
      index += index & -index;
    }
  }

  function query(index) {
    let sum = 0;
    while (index > 0) {
      sum += fenwick[index];
      index -= index & -index;
    }
    return sum;
  }

  let count = 0;
  for (let i = arr.length - 1; i >= 0; i--) {
    const r = rank(arr[i]);
    count += query(r - 1);
    update(r, 1);
  }
  return count;
}

方法对比

  • 暴力法:实现简单,但性能较差,适用于小数据量。
  • 归并排序法:高效且稳定,适合大规模数据。
  • Fenwick Tree:适用于需要动态维护的场景,但实现较复杂。

根据实际需求选择合适的方法即可。

标签: 逆序js
分享给朋友:

相关文章

js实现

js实现

JavaScript 实现方法 JavaScript 是一种广泛使用的编程语言,适用于网页开发、服务器端编程以及移动应用开发。以下是几种常见的 JavaScript 实现方法: 网页交互功能 使用…

js实现

js实现

实现 JavaScript 功能的方法 在 JavaScript 中实现特定功能通常涉及多个步骤。以下是常见的实现方法: 基础语法和变量声明 使用 let 或 const 声明变量: let…

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现分页

js实现分页

分页的基本实现思路 在JavaScript中实现分页功能通常需要结合前端和后端逻辑。前端负责渲染分页控件和处理用户交互,后端负责提供分页数据。 前端分页实现 纯前端分页适用于数据量较小的情况,可以直…

js实现轮播图

js实现轮播图

基础轮播图实现 使用HTML、CSS和JavaScript实现一个简单的自动轮播图。HTML结构包含一个容器和多个图片项。 <div class="slider"> <div…

js实现打印

js实现打印

使用window.print()方法实现打印 在JavaScript中,可以通过调用window.print()方法直接触发浏览器的打印功能。这会打开系统的打印对话框,用户可以选择打印机和设置打印选项…