算法-4-归并排序

 归并排序

public class Code01_MergeSort {// 递归方法实现public static void mergeSort1(int[] arr) {if (arr == null || arr.length < 2) {return;}process(arr, 0, arr.length - 1);}// 请把arr[L..R]排有序// l...r N// T(N) = 2 * T(N / 2) + O(N)// O(N * logN)public static void process(int[] arr, int L, int R) {if (L == R) { // base casereturn;}int mid = L + ((R - L) >> 1);process(arr, L, mid);process(arr, mid + 1, R);merge(arr, L, mid, R);}public static void merge(int[] arr, int L, int M, int R) {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];}}// 非递归方法实现public static void mergeSort2(int[] arr) {if (arr == null || arr.length < 2) {return;}int N = arr.length;// 步长int mergeSize = 1;while (mergeSize < N) { // log N// 当前左组的,第一个位置int L = 0;while (L < N) {if (mergeSize >= N - L) {//左边都凑不够步长直接退出break;}int M = L + mergeSize - 1;int R = M + Math.min(mergeSize, N - M - 1);//如果没超那就是r=m+步长merge(arr, L, M, R);L = R + 1;}// 防止溢出,N可能很大,步长每次要*2,如果步长大于N/2再成二就溢出if (mergeSize > N / 2) {break;}mergeSize <<= 1;}}// for testpublic static int[] generateRandomArray(int maxSize, int maxValue) {int[] arr = new int[(int) ((maxSize + 1) * Math.random())];for (int i = 0; i < arr.length; i++) {arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());}return arr;}// for testpublic static int[] copyArray(int[] arr) {if (arr == null) {return null;}int[] res = new int[arr.length];for (int i = 0; i < arr.length; i++) {res[i] = arr[i];}return res;}// for testpublic static boolean isEqual(int[] arr1, int[] arr2) {if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {return false;}if (arr1 == null && arr2 == null) {return true;}if (arr1.length != arr2.length) {return false;}for (int i = 0; i < arr1.length; i++) {if (arr1[i] != arr2[i]) {return false;}}return true;}// for testpublic static void printArray(int[] arr) {if (arr == null) {return;}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " ");}System.out.println();}// for testpublic static void main(String[] args) {int testTime = 500000;int maxSize = 100;int maxValue = 100;System.out.println("测试开始");for (int i = 0; i < testTime; i++) {int[] arr1 = generateRandomArray(maxSize, maxValue);int[] arr2 = copyArray(arr1);mergeSort1(arr1);mergeSort2(arr2);if (!isEqual(arr1, arr2)) {System.out.println("出错了!");printArray(arr1);printArray(arr2);break;}}System.out.println("测试结束");}}

求小和

public class Code02_SmallSum {public static int smallSum(int[] arr) {if (arr == null || arr.length < 2) {return 0;}return process(arr, 0, arr.length - 1);}// arr[L..R]既要排好序,也要求小和返回// 所有merge时,产生的小和,累加// 左 排序   merge// 右 排序  merge// mergepublic static int process(int[] arr, int l, int r) {if (l == r) {return 0;}// l < rint mid = l + ((r - l) >> 1);return process(arr, l, mid) + process(arr, mid + 1, r) + merge(arr, l, mid, r);}public static int merge(int[] arr, int L, int m, int r) {int[] help = new int[r - L + 1];int i = 0;int p1 = L;int p2 = m + 1;int res = 0;while (p1 <= m && p2 <= r) {res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 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 < help.length; i++) {arr[L + i] = help[i];}return res;}// for testpublic static int comparator(int[] arr) {if (arr == null || arr.length < 2) {return 0;}int res = 0;for (int i = 1; i < arr.length; i++) {for (int j = 0; j < i; j++) {res += arr[j] < arr[i] ? arr[j] : 0;}}return res;}// for testpublic static int[] generateRandomArray(int maxSize, int maxValue) {int[] arr = new int[(int) ((maxSize + 1) * Math.random())];for (int i = 0; i < arr.length; i++) {arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());}return arr;}// for testpublic static int[] copyArray(int[] arr) {if (arr == null) {return null;}int[] res = new int[arr.length];for (int i = 0; i < arr.length; i++) {res[i] = arr[i];}return res;}// for testpublic static boolean isEqual(int[] arr1, int[] arr2) {if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {return false;}if (arr1 == null && arr2 == null) {return true;}if (arr1.length != arr2.length) {return false;}for (int i = 0; i < arr1.length; i++) {if (arr1[i] != arr2[i]) {return false;}}return true;}// for testpublic static void printArray(int[] arr) {if (arr == null) {return;}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " ");}System.out.println();}// for testpublic static void main(String[] args) {int testTime = 500000;int maxSize = 100;int maxValue = 100;boolean succeed = true;for (int i = 0; i < testTime; i++) {int[] arr1 = generateRandomArray(maxSize, maxValue);int[] arr2 = copyArray(arr1);if (smallSum(arr1) != comparator(arr2)) {succeed = false;printArray(arr1);printArray(arr2);break;}}System.out.println(succeed ? "Nice!" : "Fucking fucked!");}}

 

求逆序对 

public class Code03_ReversePair {public static int reverPairNumber(int[] arr) {if (arr == null || arr.length < 2) {return 0;}return process(arr, 0, arr.length - 1);}// arr[L..R]既要排好序,也要求逆序对数量返回// 所有merge时,产生的逆序对数量,累加,返回// 左 排序 merge并产生逆序对数量// 右 排序 merge并产生逆序对数量public static int process(int[] arr, int l, int r) {if (l == r) {return 0;}// l < rint mid = l + ((r - l) >> 1);return process(arr, l, mid) + process(arr, mid + 1, r) + merge(arr, l, mid, r);}public static int merge(int[] arr, int L, int m, int r) {int[] help = new int[r - L + 1];int i = help.length - 1;int p1 = m;int p2 = r;int res = 0;while (p1 >= L && p2 > m) {res += arr[p1] > arr[p2] ? (p2 - m) : 0;help[i--] = arr[p1] > arr[p2] ? arr[p1--] : arr[p2--];}while (p1 >= L) {help[i--] = arr[p1--];}while (p2 > m) {help[i--] = arr[p2--];}for (i = 0; i < help.length; i++) {arr[L + i] = help[i];}return res;}// for testpublic static int comparator(int[] arr) {int ans = 0;for (int i = 0; i < arr.length; i++) {for (int j = i + 1; j < arr.length; j++) {if (arr[i] > arr[j]) {ans++;}}}return ans;}// for testpublic static int[] generateRandomArray(int maxSize, int maxValue) {int[] arr = new int[(int) ((maxSize + 1) * Math.random())];for (int i = 0; i < arr.length; i++) {arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());}return arr;}// for testpublic static int[] copyArray(int[] arr) {if (arr == null) {return null;}int[] res = new int[arr.length];for (int i = 0; i < arr.length; i++) {res[i] = arr[i];}return res;}// for testpublic static boolean isEqual(int[] arr1, int[] arr2) {if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {return false;}if (arr1 == null && arr2 == null) {return true;}if (arr1.length != arr2.length) {return false;}for (int i = 0; i < arr1.length; i++) {if (arr1[i] != arr2[i]) {return false;}}return true;}// for testpublic static void printArray(int[] arr) {if (arr == null) {return;}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " ");}System.out.println();}// for testpublic static void main(String[] args) {int testTime = 500000;int maxSize = 100;int maxValue = 100;System.out.println("测试开始");for (int i = 0; i < testTime; i++) {int[] arr1 = generateRandomArray(maxSize, maxValue);int[] arr2 = copyArray(arr1);if (reverPairNumber(arr1) != comparator(arr2)) {System.out.println("Oops!");printArray(arr1);printArray(arr2);break;}}System.out.println("测试结束");}}

num的右边有多少个数*2后依然小于num,求个数

总思路不变左面求+右边求+总merge 

 


public class Code04_BiggerThanRightTwice {public static int biggerTwice(int[] arr) {if (arr == null || arr.length < 2) {return 0;}return process(arr, 0, arr.length - 1);}public static int process(int[] arr, int l, int r) {if (l == r) {return 0;}// l < rint mid = l + ((r - l) >> 1);return process(arr, l, mid) + process(arr, mid + 1, r) + merge(arr, l, mid, r);}public static int merge(int[] arr, int L, int m, int r) {// [L....M]   [M+1....R]int ans = 0;// 目前囊括进来的数,是从[M+1, windowR)int windowR = m + 1;for (int i = L; i <= m; i++) {while (windowR <= r && arr[i] > (arr[windowR] * 2)) {windowR++;}ans += windowR - 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++];}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;}// for testpublic static int comparator(int[] arr) {int ans = 0;for (int i = 0; i < arr.length; i++) {for (int j = i + 1; j < arr.length; j++) {if (arr[i] > (arr[j] << 1)) {ans++;}}}return ans;}// for testpublic static int[] generateRandomArray(int maxSize, int maxValue) {int[] arr = new int[(int) ((maxSize + 1) * Math.random())];for (int i = 0; i < arr.length; i++) {arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());}return arr;}// for testpublic static int[] copyArray(int[] arr) {if (arr == null) {return null;}int[] res = new int[arr.length];for (int i = 0; i < arr.length; i++) {res[i] = arr[i];}return res;}// for testpublic static boolean isEqual(int[] arr1, int[] arr2) {if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {return false;}if (arr1 == null && arr2 == null) {return true;}if (arr1.length != arr2.length) {return false;}for (int i = 0; i < arr1.length; i++) {if (arr1[i] != arr2[i]) {return false;}}return true;}// for testpublic static void printArray(int[] arr) {if (arr == null) {return;}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " ");}System.out.println();}// for testpublic static void main(String[] args) {int testTime = 500000;int maxSize = 100;int maxValue = 100;System.out.println("测试开始");for (int i = 0; i < testTime; i++) {int[] arr1 = generateRandomArray(maxSize, maxValue);int[] arr2 = copyArray(arr1);if (biggerTwice(arr1) != comparator(arr2)) {System.out.println("Oops!");printArray(arr1);printArray(arr2);break;}}System.out.println("测试结束");}}

 

R=M+1,R是开区间取不到,

当i在L处,R来到M+1处,R走不动,停,i往右走到3处,R能走走三个来到4位置,那一共几个数?

R-(M+1)个数

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

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

相关文章

C++入门(上)

文章目录 1:什么是C2.C的发展史3:C关键字(C98)4:命名空间4.1:命名空间的概念4.2:命名空间的定义4.3:命名空间的使用4.3.1加命名空间的名称以及域作用限定符4.3.2:使用using将命名空间中某个成员引入4.3.3:使用using namespace 命名空间名称展开命名空间代码1代码2 5:C输入与输出…

Android Jetpack Compose 沉浸式状态栏的实现

目录 概述效果展示代码实现总结 概述 说到沉浸式状态栏&#xff0c;很多小伙伴可能不太熟悉&#xff0c;其实让Android的状态栏的颜色和APP的主题颜色相同&#xff0c;给人感觉状态栏和APP就是一体的。沉浸式的状态栏让页面看起来更舒服&#xff0c;实现沉浸式状态栏也很简单&…

Stable Diffusion 模型下载:DreamShaper(梦想塑造者)

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 DreamShaper 是一个分格多样的大模型&#xff0c;可以生成写实、原画、2.5D 等多种图片&#xff0c;能生成很棒的人像和风景图。 条目内容类型大模型基础模型SD 1…

vs2019 - signtool签名和验签的手工操作

文章目录 vs2019 - signtool签名和验签的手工操作概述笔记导入根证书时间戳服务器的选择code sign - 签名文件在代码签名(code sign)前后的区别签名后, 查看属性, 是正常的.用signtool命令行进行验签移除签名END vs2019 - signtool签名和验签的手工操作 概述 signtool是进行c…

django报错:Cannot use ImageField because Pillow is not installed

1、问题概述 ERRORS: accounts.User.avatar: (fields.E210) Cannot use ImageField because Pillow is not installed. HINT: Get Pillow at https://pypi.org/project/Pillow/ or run command "python -m pip install Pillow". System check identified 1 …

iOS AlDente 1.0自动防过充, 拯救电池健康度

经常玩iOS的朋友可能遇到过长时间过充导致的电池鼓包及健康度下降问题。MacOS上同样会出现该问题&#xff0c;笔者用了4年的MBP上周刚拿去修了&#xff0c;就是因为长期不拔电源的充电&#xff0c;开始还是电量一半的时候不接电源会黑屏无法开机&#xff0c;最后连着电源都无法…

Lua: 一门轻量级、高效的脚本语言

Lua: 一门轻量级、高效的脚本语言 在当今软件开发的领域中&#xff0c;寻找一门既灵活又高效的脚本语言&#xff0c;一直是开发者们追求的目标。Lua作为一门小巧、高效、可嵌入的脚本语言&#xff0c;已经成为了众多开发者的首选之一。无论是游戏开发、嵌入式系统、Web 开发还是…

《统计学简易速速上手小册》第8章:贝叶斯统计(2024 最新版)

文章目录 8.1 贝叶斯理论基础8.1.1 基础知识8.1.2 主要案例&#xff1a;疾病诊断8.1.3 拓展案例 1&#xff1a;垃圾邮件过滤8.1.4 拓展案例 2&#xff1a;财经新闻对股价的影响 8.2 贝叶斯方法的应用8.2.1 基础知识8.2.2 主要案例&#xff1a;个性化推荐系统8.2.3 拓展案例 1&a…

C#使用重载方法实现不同类型数据的计算

目录 一、涉及到的相关知识 1.重载的方法 2.Convert.ToInt32(String)方法 3.判断字符串是否带有小数点 二、实例 1.示例 2.生成成果 一、涉及到的相关知识 1.重载的方法 重载方法就是方法名称相同&#xff0c;但是每个方法中参数的数据类型、个数或顺序不同的方法。如果…

导数的几何意义【高数笔记】

1. 高数中的导数几何意义&#xff0c;与中学中斜率的联系 2. 导函数与导数的区别和联系又是什么 3. 导数的几何意义的题型是什么 4. 这些题型又有哪些区别 5. 点在曲线外和点在曲线上&#xff0c;需要注意什么 6. 法线和切线有什么关系 7. 法线是什么

《统计学简易速速上手小册》第6章:多变量数据分析(2024 最新版)

文章目录 6.1 主成分分析&#xff08;PCA&#xff09;6.1.1 基础知识6.1.2 主要案例&#xff1a;客户细分6.1.3 拓展案例 1&#xff1a;面部识别6.1.4 拓展案例 2&#xff1a;基因数据分析 6.2 聚类分析6.2.1 基础知识6.2.2 主要案例&#xff1a;市场细分6.2.3 拓展案例 1&…

git revert回退某次提交

请直接看原文: 【git revert】使用以及理解&#xff08;详解&#xff09;_git revert用法-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- 前言 试验得知:用Reset HEAD方…