归并排序-面试例子

小数和问题

描述
在一个数组中,一个数左边比它小的数的总和,叫数的小和,所有数的小和累加起来,叫数组小和。求数组小和。
例子
5 2 6 1 7
小和原始的求法是:任何一个数左边比它小的数累加起来。
5左边比它小数累加:0
2左边比它小数累加:0
6左边比它小数累加:5 + 2 = 7
1左边比它小数累加:0
7左边比它小数累加:5 + 2 + 6 + 1 = 14
总共21。
思路
如果左侧某数a比右侧某数b小,则在求b的小和的时候,肯定会累加一个a,即sum+=a。
反过来,在遍历到a的时候,如果我们知道右侧有几个数比a大,则可以提前知道会累加几个a
使用归并排序时恰好有左右对比操作,所以使用归并排序来做
即:
每个数右边比它大的数的个数 * 这个数自身
所以:
在原来归并排序的基础上,增加一个ans用于记录结果
在进行归并时左侧<右侧时产生小数 n * number
小和求法还可以是:每个数右边比它大的数的个数 * 这个数自身5 2 6 1 7
5的右边比它大的数的个数:2个(6和7),所以产生:2个 * 5 = 10
2的右边比它大的数的个数:2个(6和7),所以产生:2个 * 2 = 4
6的右边比它大的数的个数:1个(7),所以产生:1个 * 6 = 6
1的右边比它大的数的个数:1个(7),所以产生:1个 * 1 = 1
7的右边比它大的数的个数:0个,所以产生:0个 * 7 = 0
总共21。
code

非递归

public static int smallSum(int [] arr){if(arr == null || arr.length <2)return 0;int [] help = new int[arr.length];int step = 1;int N = arr.length;int L = 0;int ans = 0;while (step < N){L = 0;while (L < N){//左组最后一个数位置int m = L + step - 1;if(m >= N){break;}if(step >= N - L){break;}int R = Math.min(m+step,N-1);ans += merge(arr,L,m,R,help);L = R + 1;}if(step > N/2){break;}step <<= 1;}return ans;}public static int merge(int[] arr,int l,int m,int r,int [] help){//help indexint i = 0;//p1 左侧开始index,p2 右侧开始indexint p1 = l;int p2 = m+1;//结果保存int ans = 0;while (p1 <= m && p2 <= r){ans += arr[p1]<arr[p2]?arr[p1] *(r-p2+1):0;help[i++] = arr[p1]<arr[p2]?arr[p1++]:arr[p2++];}while (p1 <= m){help[i++] = arr[p1++];}while (p2 <= r){help[i++] = arr[p2++];}for (i = 0; i < r-l+1 ; i++) {arr[l+i] = help[i];}return ans;}

递归

    public static int progress(int [] arr,int l,int r,int [] help){if(l == r)return 0;int m = l + ((r -l) >> 1);return progress(arr,l,m,help)+ progress(arr,m+1,r,help)+ merge(arr,l,m,r,help);}

逆序对问题

描述
一个数组中,左边的数比右边的数大,求有多少个这样的组合

比如  [3,1,0,4,3,1] 有7个逆序对,分别是

(3,1),(3,0),(3,1)

(1,0)

(4,3),(4,1)

(3,1)

code
    //递归public static int reversePair(int [] arr){if(arr == null || arr.length <2)return 0;return progress(arr,0,arr.length -1);}public static int progress(int [] arr,int l,int r){if(l == r)return 0;int m = l + ((r-l)>>1);return progress(arr,l,m)+progress(arr,m+1,r)+merge(arr,l,m,r);}//非递归public static int reversePair2(int [] arr){if(arr == null || arr.length < 2)return 0;int ans = 0;int L = 0;int N = arr.length;int step = 1;while (step < N){L = 0;while (L < N){if(L+step >= N)break;int m = L + step - 1;if(m >= N)break;int r = Math.min(N-1,m+step);int temp = merge(arr,L,m,r);ans += temp;L = r + 1;}if(step > N/2)break;step <<= 1;}return ans;}public static int merge(int [] arr,int L,int M,int R){// 先算有多少逆序对// 和归并过程分离int res = 0;int p = M + 1;for (int i = L; i <= M; i++) {while (p <= R && arr[i] > arr[p]) {p++;}res += p - (M + 1);}// 下面完全和归并排序一样int[] help = new int[R - L + 1];int i = 0;int p1 = L;int p2 = M + 1;while (p1 <= M && p2 <= R) {help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];}// 要么p1越界了,要么p2越界了while (p1 <= M) {help[i++] = arr[p1++];}while (p2 <= R) {help[i++] = arr[p2++];}for (i = 0; i < help.length; i++) {arr[L + i] = help[i];}return res;}

左边大于右边倍数的数

描述
在一个数组中,
对于每个数num,求有多少个后面的数 * 2 依然<num,求总个数
比如:[3,1,7,0,2]
3的后面有:1,0
1的后面有:0
7的后面有:0,2
0的后面没有
2的后面没有
所以总共有5个
思路
右边有多少个数*2比左边的数小
在归并排序过程中,分组后左侧有序,右侧有序,在进行左右侧合并时,统计验证关系【2倍关系】
这样可以得到该左侧位置相对于右侧位置的2倍关系统计和
code
//递归public static int biggerThatRightTwice(int []arr){if(arr == null || arr.length<2){return 0;}return progress(arr,0,arr.length-1);}public static int progress(int[] arr,int l,int r){if(l == r){return 0;}int m = l + ((r-l)>>1);System.out.println("l,m,r:"+l+","+m+","+r);return progress(arr,l,m)+progress(arr,m+1,r)+merge(arr,l,m,r);}//非递归public static int biggerThatRightTwice2(int [] arr){if(arr == null || arr.length <2)return 0;int L = 0;int step = 1;int N = arr.length;int ans = 0;while (step < N){L = 0;while (L < N){if(step >= N-L)break;int m = L + step - 1;if(m >= N)break;int r = Math.min(m+step,N-1);ans += merge(arr,L,m,r);L  = r + 1;}if(step > N/2)break;step <<=1;}return ans;}public static int merge(int[] arr,int l,int m,int r){//[l,m] [m+1,r]进行归并,其中[l,m],[m+1,r]分别已经有序//先计算int p1 = l,p2 = m+1;int ans = 0;//左侧遍历lwhile (p1 <= m){//右侧遍历while (p2 <= r){//如果左侧 > 右侧 * 2,则继续判断,知道不满足条件//当不满足条件时,则右侧从开始位置m+1到p2位置为p1满足条件的数if(arr[p1] > arr[p2] *2){p2++;}else{break;}}//p2 - (m+1) => [m+1,p2) 即从m+1到p2个元素个数,不包含p2ans += (p2 - (m+1));p1++;}//再进行归并int [] help = new int[r-l+1];int i = 0;p1 = l;p2 = m+1;while (p1<=m && p2<=r){help[i++] = arr[p1]<arr[p2]?arr[p1++]:arr[p2++];}while (p1<=m){help[i++] = arr[p1++];}while (p2<=r){help[i++] = arr[p2++];}for(i=0;i<help.length;i++){arr[l+i] = help[i];}return ans;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/76406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试系列 - Redis持久化机制详解

目录 一、Redis 持久化机制 二、混合使用 RDB 和 AOF 三、 RDB(Redis DataBase)详解 四、AOF&#xff08;Append-Only File&#xff09;详解 Redis 是一个内存数据库&#xff0c;为了持久化数据以确保数据不会在服务器重启时丢失&#xff0c;Redis 提供了两种主要的持久化机…

执行 JUnit 单元测试前,修改环境变量

同一份代码&#xff0c;在不改变配置文件的情况下&#xff0c;可以连接不同的数据库&#xff0c;进行JUnit测试。 非开发、测试、生产环境的区别。而是 我就站在这里&#xff0c;指哪打哪&#xff01; 避免重复造轮子&#xff0c;参考博文&#xff1a; 使用junit&spri…

python main 函数-启动-传递参数 python 打包 exe C# 进程传参

Part1:Python main 传递参数 在Python编程中&#xff0c;我们经常需要从命令行或其他外部环境中获取参数。Python提供了一种简单而灵活的方式来处理这些参数&#xff0c;即通过main函数传参 1.python main 函数-启动-传递参数 test.py import sysdef main():# 获取命令行参…

QT 自定义信号

自定义信号&#xff0c;需要 1.在singnals:区域下写信号函数&#xff0c;以及函数对应的参数 2. 需要emit关键字进行发射信号 3. 在需要处理该信号的其他类中&#xff0c;建立信号和其信号槽函数connect() 4. 在其他类中创建信号处理槽函数 #include "mythread.h"my…

Linux 中的 col 命令及示例

Linux 系统中的col命令用于过滤掉反向换行,使输出看起来更加正确,只有正向和半正向换行,并尽可能用制表符替换空白字符。这在处理 nroff 和 tbl 的输出时被证明是有用的。col 实用程序只是从标准输入读取并写入标准输出。 句法: 列 [-bfhpx] [-l num] col [-bfhpx] [-l nu…

C盘清理教程

C盘清理教程 首先使用space Sniffer 扫一下c盘&#xff0c;然后看一下到底是哪个文件这么大 第二步&#xff0c;创建软链接。 首先将我们需要移动的文件的当前路径拷贝下来&#xff1a;C:\Users\Tom\Desktop\test-link\abc\ghi.txt 然后假设剪切到D盘下&#xff1a;D:\ghi.…

Linux 中的 cmp 命令及示例

Linux/UNIX 中的cmp命令用于逐字节比较两个文件,帮助您找出两个文件是否相同。 当 cmp 用于比较两个文件时,如果发现差异,则将第一个不匹配的位置报告到屏幕,如果没有发现差异,即比较的文件相同。cmp 不显示任何消息,如果比较的文件相同,则仅返回提示。语法: cmp [选项…

基于改进人工蜂群算法的 K 均值聚类算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

RBTree模拟实现

一、概念 概念&#xff1a;红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出俩倍&a…

pdf拆分成多个文件的方法以及注意事项

PDF是一种非常流行的文件格式&#xff0c;但有时候我们需要将一个大的PDF文件拆分成多个小的文件&#xff0c;以便于管理和分享。本文将介绍一些拆分PDF文件的方法以及需要注意的事项。 AdobeAcrobat是一款专业的PDF编辑软件&#xff0c;可以轻松地拆分PDF文件。以下是使用Adob…

基于SpringBoot开发的停车位管理系统(调用百度地图api)

文章目录 项目介绍主要功能截图:前台:后台部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot开发的停车位管…

【建站教程】使用阿里云服务器怎么搭建网站?

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网以搭建WordPress网站博客为例&#xff0c;阿小云来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流程&#x…

Fiddler Inspectors AES解密插件开发

Fiddler Inspectors AES解密插件开发 业务数据做了AES加密处理&#xff0c;抓包看不到具体数据&#xff0c;找不到合适的插件 就自己动手写了一个&#xff0c;主要是使用fiddler提供的一个基类和三个接口 Inspector2, IRequestInspector2, IResponseInspector2&#xff0c; IB…

【2023研电赛】兆易创新命题三等奖: 低成本单母线电流永磁同步无感驱动器

本文为2023年第十八届中国研究生电子设计竞赛兆易创新企业命题三等奖以及决赛最佳论文奖分享&#xff0c;参加极术社区的【有奖活动】分享2023研电赛作品扩大影响力&#xff0c;更有丰富电子礼品等你来领&#xff01;&#xff0c;分享2023研电赛作品扩大影响力&#xff0c;更有…

通过阿贝云免费云服务器部署vue3+vite项目

通过阿贝云免费云服务器部署vue3vite项目 阿贝云&#xff1a;https://www.abeiyun.com 首先访问阿贝云登录后申请服务器&#xff0c;需要关注微信公众号绑定 然后我们给服务器安装操作系统&#xff0c;这里我使用了centos7.6 这里我使用finalshell 连接服务器 我们首先配置ng…

EPICS电机支持(asynMotor)

EPICS电机支持 1&#xff09; 顶层对象是EPICS motor记录 已经对这个对象编写了很多代码&#xff1a;spec&#xff0c;IDL和Python类等 2&#xff09;下一层是EPICS设备支持 了解motor记录&#xff0c;与驱动会话 3&#xff09;最底层是EPICS驱动 对motor记录一无所知&am…

如何提取视频中的音频?几个步骤轻松提取

在现今社交媒体的风靡下&#xff0c;许多人都会使用手机录制视频来记录生活中的美好瞬间。有时候&#xff0c;我们也会想要提取视频中的音频&#xff0c;例如将自己的演讲录音分发给听众。本文将会介绍如何在手机上提取视频中的音频以及需要注意的事项。 使用应用程序 首先&am…

Linux命令200例:write用于向特定用户或特定终端发送信息

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…

Android高德地图截屏功能(可包含自定义控件)

一、不包含自定义控件 地图 SDK 支持对当前屏幕显示区域进行截屏&#xff0c;可以对地图、覆盖物&#xff08;包含信息窗口&#xff09;、Logo进行截取屏幕&#xff0c;这其中不包括地图控件、Toast窗口。 详细示例如下&#xff1a; // 对地图进行截屏aMap!!.getMapScreenSho…

正交试验设计法

正交实验设计 一、什么是正交试验设计法&#xff1f; 是一种成对测试交互的系统的统计方法。它提供了一种能对所有变量对的组合进行典型覆盖&#xff08;均匀分布&#xff09;的方法。 可以从大量的试验点中挑出适量的、有代表性的点&#xff0c;利用“正交表”&#xff0c;…