剑指Offer——数组中的逆序对(JS实现)

简介: 剑指Offer——数组中的逆序对(JS实现)

题目描述

image.png

解题思路

  • 我刚开始看到本题,首先想到的是暴力解法,也就是通过for循环进行不断遍历,结果超时。
  • 看了题解才知道,解决逆序对的问题,往往通过归并排序
  • 本题考查的本质还是归并排序,只是在归并排序的基础上,增加了一行代码而已。
  • 归并排序使用的是分治法的思想,本题就是建立在还是合并的时候,进行统计计算,最终求出结果。

解题代码一(暴力法:超时)

var reversePairs = function(nums) {
    let flag = 0;
    for (let i = 0; i < nums.length; i++) {
        const temp = nums.slice(i+1);
        for (let v of temp) {
            if (v < nums[i]) {
                flag++;
            }
        }
    }
    return flag;
};

解题代码二(归并排序)

var reversePairs = function(nums) {
    // !采用归并排序的思想
    // 定义变量存储逆序对的数量
    let sum = 0;
    // 归并排序的返回结果赋值给sum
    mergeSort(nums);
    // 将最终结果进行返回
    return sum;
    // 归并排序函数
    function mergeSort(nums) {
        // 如果数组的长度小于2,说明只有一个元素的时候,我们返回这个数组,即递归的结束条件
        if (nums.length < 2) return nums;
        // 如果数组的长度不小于2,说明还没有分彻底 ,下面继续分
        let mid = Math.floor(nums.length / 2);
        // 左边的子数组
        let left = nums.slice(0,mid);
        // 右边的子数组
        let right = nums.slice(mid);
        // 将拆分好的左右子数组投入到合并函数中
        return merge(mergeSort(left),mergeSort(right));
    }
    // 合并函数(用户将拆分好的子数组进行合并)
    function merge(left,right) {
        // 定义一个存储合并排好顺序的总数组(包含左右子数组的)
        const res = [];
        // 左子数组的长度
        const leftLen = left.length;
        //  右子数组的长度
        const rightLen = right.length;
        // 开始循环遍历,是以res的下标为基础进行遍历的(i是左子数组的下标,j是右子树组的下标,index是res的下标)
        for (let i = 0,j = 0,index=0;index < leftLen + rightLen; index++) {
            // 下面的判断应先对越界条件进行判断
            if (i >= leftLen) {
                // 如果i越界说明,左子数组已经遍历完,此时res直接添加右子数组的下标指向的元素即可
                res.push(right[j++])
            } else if (j >= rightLen) {
                // 如果j越界,说明右子数组已经遍历完了,此时res直接添加左子数组下标指向的元素即可
                res.push(left[i++]);
            } else if (left[i] <= right[j]) {
                // 如果左子数组下标指向的元素小于等于右子数组下标指向的元素,此时不存在逆序对,将左子数组对应的结果加到res数组即可
                res.push(left[i++])
            } else {
                // 如果左子数组下标指向的元素大于右子数组下标指向的元素,此时是存在逆序对的
                res.push(right[j++]);
                sum = sum + leftLen - i
            }
        }
        // 返回合并好的数组(此处易错)
        return res; 
    }
};

总结(本题给我们的启示思路)

  • 启示一:学会使用归并排序
  • 启示二:学会归并排序的分治思想
相关文章
|
29天前
|
自然语言处理 前端开发 JavaScript
🛠️ JavaScript数组操作指南:20个精通必备技巧🚀
本文详细介绍了 JavaScript 中的 20 个高效数组操作技巧,涵盖了从基本的添加、移除元素,到数组转换和去重等高级操作。强调了不可变性的重要性,提供了清晰的代码示例,帮助开发者编写更整洁和高效的代码。无论是新手还是经验丰富的开发者,这些技巧都将显著提升您的编码能力,使您在项目中更具竞争力。
21 2
|
1月前
|
JavaScript 前端开发 测试技术
JS都有哪些操作数组的方法
JS都有哪些操作数组的方法
20 3
|
1月前
|
缓存 JavaScript 前端开发
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
31 1
|
1月前
|
JavaScript 前端开发 API
JS中数组的方法flat()怎么用
JS中数组的方法flat()怎么用
13 0
|
1月前
|
JavaScript 前端开发 索引
JavaScript中数组、对象等循环遍历的常用方法介绍(一)
JavaScript中数组、对象等循环遍历的常用方法介绍(一)
20 0
|
Web App开发 JavaScript 前端开发
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
95 2
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
118 4
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
81 4
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
72 4