排序算法在数组题目中的应用

力扣刷题之排序算法篇 力扣刷题之排序算法篇 为了提高自我对各种算法了理解,和提高解决实际问题的能力,在力扣网进行刷题,由于我熟练掌握两种语言,即每道题提供java,和Python的解题通过代码!如果内容有类似的可以联系我进行删除。 题目来源和相关知识请查看:力扣 文章目录力扣刷题之排序算法篇冒泡排序 冒泡排序 冒泡排序:依存比较第i个关键字和第i+1个关键字,大的网排后,一趟得到最大值 先看力扣:剑指 Offer 45. 把数组排成最小的数,了解一下 练习题1:输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打 阅读详情

在做题目中可能会发现一些类型的题目具有一定的解题倾向性。在数组题目中,跟数组中大小顺序有关,往往可以使用排序算法,并在排序的过程中,做相应的处理。这种思路在二叉树题目尤其突出,二叉树的题目很多情况下都是需要遍历二叉树。根据题目还需要选择相应的排序算法或者二叉树遍历类型。

在剑指offer中有一道关于数组中逆序对的题目,这道题就很好的体现了排序算法在数组中的应用。


题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

数组中的逆序对,题目详细链接


这道题的核心思想就是使用归并排序的思想,并在合并子数组的时候,对数组中的逆序对进行统计,代码如下。

public class Solution {
    public static int InversePairs(int [] array) {
        if(array == null || array.length == 0)
            return 0;

        //辅助数组
        int[] copy = new int[array.length];
        for(int i=0; i<array.length; i++){
            copy[i] = array[i];
        }

        int count = InversePairsCore(array, copy, 0, array.length-1);
        return count;
    }

    private static int InversePairsCore(int[] array, int[] copy, int low, int high){
        if(low == high)
            return 0;

        //将数组分成两部分,左边的low到mid,和右边的mid+1到high,递归计算左边和右边总共有多少对逆序对
        int mid = (low+high)/2;
        //递归调用
        int leftCount = InversePairsCore(array, copy, low, mid)%1000000007;
        int rightCount = InversePairsCore(array,copy, mid+1, high)%1000000007;
        //以上部分就是归并排序中的拆分部分, 下面是归并部分

        int count = 0;
        //i初始化为前半段最后一个数组的下标, 指向前半部分的数组的最后一个元素
        int i = mid;
        //j初始化为后半段最后一个数字的下标, 指向后半部分的数组的最后一个元素
        int j = high;
        int locCopy = high;
        //这里是循环合并相邻的子数组,是循环比较左右边中的数组的每个元素
        //这里的数组都是排好序的,如果array[i]大于此时的array[j],则array[i]大于mid+1到j的所有元素
        //这样此时的i就与mid+1到j的元素都组成一对逆序对

        //合并并且计算这两个相邻数组的逆序对的个数, 归并排序的归并部分
        while(i >= low && j >= mid + 1){
            //这里都是从左右数组的最后一位开始的,然后一位一位向后循环的
            if(array[i] > array[j]){
                //如果array[i]大于array[j], 则array[i]大于从array[mid+1]到array[j]的所有元素, 即增加了逆序对 j-mid 个
                count = count + j - mid;
                //这里是合并后的数组,此时将array[i]放到最终合并数组空着的最后一位
                copy[locCopy--] = array[i--];
                if(count >= 1000000007)
                    count %= 1000000007;
            }else{
                //其实这里合并后的数组,就是将array[i]和array[j]中较大者,
                //依次放到合并数组空着的最后一位
                copy[locCopy--] = array[j--];
                //copy[locCopy] = array[j];
                //locCopy--;
                //j--;
            }
        }

        //如果当前半部分或者后半部分中有一个数组已经在上边的while循环遍历完了, 但是另一个数组还没有遍历完
        //因为这两个数组都是自身已经排序好了, 所以只需要将剩余的元素依次放到辅助数组中即可
        //以下两个循环最多只可能执行一个
        for(;i>=low;i--){
            copy[locCopy--] = array[i];
        }

        for(;j>=mid+1; j--){
            copy[locCopy--] = array[j];
        }

        //这里是复用了原数组的变量, 将已经排序好的数组部分, 复制回原数组部分
        for(int s = low; s <= high; s++){
            array[s] = copy[s];
        }

        return (leftCount + rightCount + count)%1000000007;
    }

    public static void main(String[] args) {
        int[] array = {7,5,6,4};
        int result = InversePairs(array);
        System.out.println(result);
    }
}

运行结果

5
数据结构经典面试题目 数据结构经典面试题目 1.数组和链表的区别,请详细解释 从逻辑结构来看: a) 数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费;数组可以根据下标直接存取。 b) 链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项,非常繁琐)链表必须根据next指针找到下一个元素 从内存存储来看: a) (静态)数组从栈中分配空间, 对于程序员方便快速,但 阅读详情

相关推荐

从PTA题目看插入排序:新手如何快速掌握算法核心思想?

本文通过PTA题目深入解析插入排序的核心思想,帮助编程新手快速掌握这一基础算法。从扑克牌整理的直观比喻到具体代码实现,详细讲解了插入排序的原理、常见错误及调试技巧,并探讨了其变体与优化方法,为算法学习打下坚实基础。

weixin_30399821的博客 357

八大排序算法总结+例题练习(正在不断补充...)

1.插入排序 1.基本介绍 直接插入排序是最简单的排序方法,每次将一个待排序的记录,插入到已经排好序的数据序列中,得到一个新的长度增1的有序表。如图9-3所示。 2.算法步骤: 1)设待排序的记录 存储在数组r[1…n]中,可以把第一个记录r[1]看作-一个有序序列。 2)依次将[国] (i=2,… n)插入到已经排好序的序列r[1…i-1]中,并保持有序性。 例如,利用直接插入排序算法对序列 {12,2,16,30,28,10,16*,20,6,18}进行非递减排序。 初始状态,把r[1]看作-一个有序

LXYDSF的博客 4375

Pspice安装教程:Windows系统完整指南(含环境变量设置)

详细讲解在Windows系统中完成Pspice安装的全过程,涵盖安装步骤与关键的环境变量设置,帮助用户顺利运行仿真工具。适合初学者快速上手pspice安装教程中的核心环节。

weixin_42230607的博客 1177

【面试算法题】十种常用排序算法详解

排序算法的稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,如果排序以后,保证这些记录的相对次序保持不变,即在原序列中,a[i]=a[j],且 a[i] 在 a[j] 之前,排序后保证 a[i] 仍在 a[j] 之前,则称这种排序算法是稳定的;否则称为不稳定的。 一.选择排序 每次从待排序的元素中选择最小的元素,依次和第1、2、3...位置的元素进行交换。这样在数组前面的部分形成有序区域。每进行一次交换,有序区域长度加一。 public static ...

indeedes的博客 5974

从零开始:手把手教你理解UBOOT的BL0、BL1、BL2启动流程

本文详细解析了嵌入式系统中UBOOT启动流程的核心三阶段:BL0、BL1和BL2。BL0作为芯片固化的ROM代码,负责最基础的硬件初始化和加载BL1;BL1(SPL)作为二级程序加载器,在SRAM中运行并初始化DRAM,为加载BL2铺路;BL2则是完整的UBOOT主体,运行于DRAM,负责最终的外设初始化和操作系统引导。文章通过代码示例和流程图,手把手教你理解从芯片上电到系统就绪的完整接力过程。

qsc901234567的博客 1143

Ubuntu升级遇到grub-efi-amd64-signed报错?3步搞定这个烦人的EFI目录问题

本文详细解析了Ubuntu系统升级时遇到的“grub-efi-amd64-signed”报错及“cannot find EFI directory”问题。通过剖析UEFI启动机制与EFI系统分区原理,提供了从诊断到修复的三步解决方案,帮助用户快速解决因EFI目录未挂载导致的升级中断,确保系统引导正常。

assembly8low的博客 585

C语言常用8种排序方法耗时测试

最近项目中用到排序算法,于是研究了一下常用的8种排序算法。由于是在8位单片机上使用,所以对内存和时间要求比较高,最好是不额外占空间,同时耗时较短。于是对常用的8中算法耗时做了个测试。通过LED的亮灭来指示算法开始执行和执行完成情况,然后用示波器测试LED管脚电平来判断算法所用时间。 8种算法代码如下: #include "sort.h" #include "math.h" #define...

HXYDJ的博客 4888

西电微机系统课程设计步进电机开环控制系统

** 微机系统与应用课程设计 课题二 步进电机开环控制系统设计** 一、程设计目的 掌握微机系统总线与各芯片管脚连接方法,提高接口扩展硬件电路的连接能力。 加深对 A/D 和并行接口芯片的工作方式和编程方法的理解。 搞懂步进电机的工作原理及控制方式,掌握开环控制系统的设计思路和实现方法。 二、课程设计的内容 手动调节电位器旋钮(0V~5V),通过 ADC0809 模拟输入水库水位 0 米~50...

qq_37015775的博客 4038

排序在实际生活中的应用

排序的目的通常是为了方便查找,或者统计最多或者最少的重复次数。 应用案例: 1.任务调度问题。在已知一天当中所有活动的开始时间和结束时间的前提下,通过排序算法使一个人在一天之内参加的活动尽可能的多。 2.在ACM竞赛中,通过排序算法对每支队伍进行现场排名。排名规则:题目数量通过率高的排名靠前,多个队伍通过的题目数目相同时,罚时少的队伍排名靠前。 **3.游戏竞赛。**游戏规则是随机一组30张图片,要求参加比赛的10人在30秒之内把图片按照从小到大顺序排序,时间最少的获胜。 4.调查问卷。为了实验的客观性,在

dally2的博客 6948

AutoSAR配置视频讲解:新建DaVinci工程

AutoSAR实验视频讲解:闪烁一颗LED实验【新建DaVinci工程】 上一篇 | 下一篇 | 总目录 实验架构图 视频本频放在了文末,下图描述了本次实验配置内容在AutoSAR架构中的位置,供大家参考 实验内容 本节课程讲解新建DaVinci工程,听上去新建工程很简单,但是还是需要很多的准备工作和细节。主要内容是新建工程和导入dbc文件和导入arxml文件的方法 主要步骤 新建DaVinci工程 导入.dbc通信矩阵文件 导入Mcal的arxml文件 实验视频2:Mcal配置 提示:版权所在,违

雪云飞星的博客 6275

AE-扭曲-变形-弧

一些AE效果的着色器实现记录

What_can_you_do的博客 1174

重新认识下数据结构与算法(二)数组的排序算法

在我们程序的开发过程中,数据不仅仅只是存储,还经常需要对数据做一定的处理。这就是算法,如果是几百条,几千条甚至几万条的数据的话,可能我们对算法的效率和时间复杂度没那么敏感。但是如果我们面对的是几百万,几千万甚至几亿,几十亿,几百亿的数据的话,那么我们对算法的要求就非常高了。下面就是我们开发中经常用到的算法。 1.数组 与数组相关的算法很多,但最基本最常见的就是排序的算法 (1)冒泡排序 冒...

linjiaen20的博客 646

硅基半导体量子点:单电子自旋量子比特技术手册

现在我们已经了解了从硅片到容错计算的全部环节,让我们用一张总览图把碎片拼成完整拼图。fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;important;important;important;color:#000!important;important;important;important;important;color:#000!

VectorShift的博客 371

超星高级语言程序设计实验作业 (实验04 数组及其在程序设计中的应用)(一)

超星高级语言程序设计实验作业 实验04 数组及其在程序设计中的应用(一) 注:以下内容仅供交流,代码都是本人自己写的,还请同学们先自己编写再进行交流。

博客 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【数据结构】数组中的问题

常见的数组问题 排序:选择排序、插入排序、堆排序、快速排序、归并排序 二分查找法 数据结构:栈、队列、堆(底层实现都是数组) … 如何写出正确的程序 example:二分查找法 番外篇:二分查找法的思想在1946年提出的,第一个没有bug的二分查找法在1962年才出现。说明一个道理:真正的实现一个完全正确的算法是复杂的,只是思考算法的思想却是简单的。 对于有序数列,才能使用二分查找法(排序的作用) 代码实现 // 二分查找法 public static int binarySe

qq_46381044的博客 1024

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【数组】相关题目

(1)——422排序->遍历每个位置->在这个位置右边搞双指针有两个去重,分别针对每个位置,以及这个位置的双指针(再旋转一次,仍然是两端递增)(2)——284①最简单的做法是用HashMap②除此以外,还有种类似于三数之和的做法,只不过内层就不是用双指针了, 而是用二分找到和基准位置加起来最接近target的数(3)——261(4)——181经典题目了,下面是双指针做法,要是碰到找茬的面试官再学其他做法得了(5)——140(5)——114。

weixin_45782139的博客 252

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。

输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。 我们首先会想到常规方法:创建一个临时数组,遍历所给数组中的所有元素,将偶数提取出来,再将临时数组中的偶数元素加入到原数组后边,但该方法存在致命缺点,临时数组的数组大小有上限,此时对于数组知识掌握不熟练的人可能会想到定义一个变量,用该变量存储数组长度,使其灵活可变,可是C语言...

jiangkun0331的博客 2598

C++题目(四)

盛大笔试: 1.求输出结果: #include "iostream" #include "vector" using namespace std; int main(void) { vectorarray; array.push_back(100); array.push_back(300); array.push_back(300); array.push_b

胜利者的经验并不复杂,那就是寻找人生的关键点,并在关键时刻竭尽全力 4175

js 将list 某个属性 组装成数组_前端面试:JS 编程题目总结(一)

前端面试中,手撕代码环节除了力扣上的算法题目之外,还有一些针对前端知识点的题目,大致有以下几类:算法类原理类应用类算法类1. 手写快排、冒泡、选择排序快速排序:/***---测试用例---**输入:[1, 34, 5, 76, 8, 6, 9, 7, 6, 3]*输出:[1, 3, 5, 6, 6, 7, 8, 9, 34, 76]**---说明---*...

weixin_35762258的博客 1687

【一刷《剑指Offer》】面试题 33:把数组排成最小的数

我们将说法换一下,对于本题而言,我们要的有效序列是:序列中任何一个元素 y,和它前的任何一个元素 x 进行有序组合形成 xy,比和他后面的任何一个元素z进行有效序列组合 yz,满足条件 xy < yz(采用字典序列排序),如 {32,31},有效组合是 3132,所以我们拍完序列之后序列变成 {31,32}。可以采用字符串来表示数字,这样就能简洁地解决大数问题。这道题的核心理解是对于排序算法的理解。通常我们所理解的排序是比较大小的,比如:升序排序的序列意思是:序列中任何一个数字都比前面的小,比后面的大。

Elena's Blog 526

一文通数据结构与算法之——数组+常见题型与解题策略+Leetcode经典题

文章目录2 数组2.1 常见题型及解题策略2.2 字符串操作基础2.3 删除数组元素2.3.1 题库列表2.4 双指针技巧2.4.1 题库列表2.5 数组类操作2.6 剑指offer 数组题:剑指 Offer 04. 二维数组中的查找剑指 Offer 11. 旋转数组的最小数字剑指 Offer 17. 打印从1到最大的n位数【剑指Offer】21、调整数组顺序使奇数位于偶数前面剑指Offer】29、顺时针打印矩阵【剑指Offer】39、数组中出现次数超过一半的数字【剑指Offer】51、数组中的逆序对【剑指

尚墨1111的博客 1084

数组实验报告-201621033002杨晓琪

一、PTA实验作业 题目1:7-27矩阵A乘以B 1. 本题PTA提交列表 最终代码: 2.设计思路(包括流程图) 设计思路:先输入矩阵A,B,然后判断矩阵A,B能否相乘:若能相乘,使矩阵A的每行分别跟矩阵B的每一列相乘,设置三个循环变量,则循环sum=sum+a[i][k]*b[k][j],输出过程注意格式;若不能相乘,输出矩阵A的行不等于矩阵B的列。 3.本...

baobak89832的博客 267

终极指南:十大排序算法原理与实战应用详解

排序算法是计算机科学的基础,也是LeetCode解题的必备技能。无论是求职面试还是日常开发,掌握排序算法的原理和应用都至关重要。本文将系统讲解十大经典排序算法的核心思想、适用场景及实现技巧,帮助你轻松应对各类排序问题。 ## 为什么排序算法如此重要? 排序算法是数据处理的基石,几乎所有程序都离不开排序操作。在LeetCode中,超过30%的题目涉及排序思想,例如[15.三数之和](https:

gitblog_00908的博客 827

数组:经典排序

LeetCode912. 堆排序 https://leetcode-cn.com/problems/sort-an-array/ 给你一个整数数组 nums,请你将该数组升序排列。 输入:nums = [5,2,3,1] 输出:[1,2,3,5] 思路 采用堆排序。 首先,将数组调整大根堆; 然后,每次将队头元素与队尾元素交换,队尾元素已放到最终位置,对队头元素向下调堆(重新调整为大根堆)。循环此操作直到大根堆中仅剩一个元素。 代码 class Solution { private: void

qq_44781747的博客 225

C语言进阶练习题——数组

本文展示了三个C语言数组操作实例:1) 使用冒泡排序对用户输入的10个整数进行降序排列;2) 在预定义数组中查找用户输入数字的下标位置;3) 计算3×3矩阵主对角线元素之和。每个程序都包含完整代码、注释说明和运行示例,分别实现了数组排序、搜索和矩阵运算功能,展示了C语言中数组的基本操作方法。

2301_80902533的博客 33
上一篇: 阿里云服务器搭建java环境详细步骤5
下一篇: 数字在排序数组中出现的次数
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值