当前位置:首页 > JavaScript

js实现查找逆序数

2026-01-31 06:12:53JavaScript

查找逆序数的实现方法

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

暴力法

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

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),但需要离散化数据。

js实现查找逆序数

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实现日历的核心是动态生成日期表格,并处理月份切换逻辑。需要计算当前月的天数、起始星期几,并动态渲染到页面上。 获取当前日期信息 通过Date对象获取当前年…

js实现类

js实现类

JavaScript 实现类的几种方式 JavaScript 是一种基于原型的语言,但在 ES6 之后引入了 class 语法糖,使得实现类更加直观。以下是几种常见的实现方式: 使用构造函数 传统的…

js实现vr

js实现vr

使用WebXR API实现VR体验 WebXR是浏览器中实现VR和AR体验的标准API,它取代了早期的WebVR。现代浏览器如Chrome、Edge和Firefox已支持WebXR。 // 初始化W…

js实现vue路由

js实现vue路由

Vue 路由的基本实现 在 Vue.js 中实现路由功能通常使用 Vue Router 库。Vue Router 是 Vue.js 官方的路由管理器,用于构建单页面应用(SPA)。 安装 Vue R…

js实现正交

js实现正交

正交的概念 正交在数学和计算机科学中通常指两个向量垂直或线性无关。在编程中,正交性常被用于设计模块化、低耦合的系统。 向量正交判断 判断两个向量是否正交可以通过点积是否为0来实现: fun…

js实现菜单

js实现菜单

实现基本HTML结构 使用HTML创建菜单的基本框架,通常包含<ul>和<li>元素。示例结构如下: <ul id="menu"> <li><…