当前位置: 首页 > ai >正文

LeetCode:912归并排序,洛谷:ACM风格

文章目录

  • 归并排序
    • acm练习风格
    • 填函数练习风格

左程云算法学习笔记
详细的笔记都注释在代码上

归并排序

acm练习风格

测试链接

package class021;// 归并排序,acm练习风格
// 测试链接 : https://www.luogu.com.cn/problem/P1177
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;public class Code01_MergeSort {public static int MAXN = 100001;public static int[] arr = new int[MAXN];public static int[] help = new int[MAXN];//merge过程中的辅助数组//arr[]和help[]是全局静态static变量,所以所有的方法都不用放参数位置。参数位没有也能直接访问到。//使用全局静态变量能少些好多东西public static int n;//通过下面输入流的读入方式,n是arr的长度public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StreamTokenizer in = new StreamTokenizer(br);PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));in.nextToken();n = (int) in.nval;for (int i = 0; i < n; i++) {in.nextToken();//不断读数据,arr[i] = (int) in.nval;//并放入arr数组}// mergeSort1(0, n - 1);mergeSort2();for (int i = 0; i < n - 1; i++) {out.print(arr[i] + " ");}out.println(arr[n - 1]);out.flush();out.close();br.close();}// 归并排序递归版// 假设l...r一共n个数// T(n) = 2 * T(n/2) + O(n)// a = 2, b = 2, c = 1// 根据master公式,时间复杂度O(n * logn)// 空间复杂度O(n) (需要额外的辅助数组)public static void mergeSort1(int l, int r) {if (l == r) {return;}int m = (l + r) / 2;mergeSort1(l, m);mergeSort1(m + 1, r);merge(l, m, r);}// 归并排序非递归版// 时间复杂度O(n * logn)// 空间复杂度O(n)public static void mergeSort2() {//从左到右,按步长=1,2,4……排完序以后再merge,不是递归,是从头一遍又一遍。//所以为什么不用传参数呢?数组是static,全局变量,那么直接方法里定义l,r,m即可// 一共发生O(logn)次for (int l, m, r, step = 1; step < n; step <<= 1) { //step是步长,这里的位运算表示每次都乘2,写成乘2也行,但是位运算比乘法运算快一点,其实秀技// 内部分组merge,时间复杂度O(n)l = 0;while (l < n) {m = l + step - 1;//0,,1,,2 这个步长是3	if (m + 1 >= n) {//发现右边界的初始越界就break,就不用merge了break;}//说明有右侧//接下来求右侧的右边界,左边界是m+1//左部分是的右边界是l+x-1,右部分和左部分是相等的长度,所以右部分的右边界是(拿l算为啥不拿m+1作为起始算?一样的,我的是思考的直接的方法(相比较多一步计算),这个是数学上简化代码上更优雅的方法)l + 2x - 1,即l + (step << 1) - 1。但是呢有可能数组没有这么长了,所以两者取min为右边界值r = Math.min(l + (step << 1) - 1, n - 1);merge(l, m, r);l = r + 1;}}}// l....r 一共有n个数// O(n)//merge不是递归方法 public static void merge(int l, int m, int r) {int i = l;//辅助数组help[]被填到了什么位置 int a = l;//a是左边有序数组的指针int b = m + 1;//b是右边有序数组的指针while (a <= m && b <= r) {//如果左右两侧都没有耗尽的话help[i++] = arr[a] <= arr[b] ? arr[a++] : arr[b++];//最经典的过程,谁小拷贝谁}// 左侧指针、右侧指针,必有一个越界、另一个不越界(所以下面两个while只会命中一个)//逻辑:哪边没耗尽就继续拷贝while (a <= m) {help[i++] = arr[a++];}while (b <= r) {help[i++] = arr[b++];}/*意义相同,下面是我写的,逻辑:哪边耗尽了就拷贝另一边while(a > m){help[i++] = arr[b++];}while (b > r){help[i++] = arr[a++];}*///至此,help[]的数字全部经过比较填写完成,限下面将其刷进原数组arr[]for (i = l; i <= r; i++) {arr[i] = help[i];}}}

在这里插入图片描述

填函数练习风格

测试链接

package class021;// 归并排序,填函数练习风格
// 测试链接 : https://leetcode.cn/problems/sort-an-array/public class Code02_MergeSort {public static int[] sortArray(int[] nums) {if (nums.length > 1) {// mergeSort1为递归方法// mergeSort2为非递归方法// 用哪个都可以// mergeSort1(nums);mergeSort2(nums);}return nums;}public static int MAXN = 50001;public static int[] help = new int[MAXN];// 归并排序递归版public static void mergeSort1(int[] arr) {sort(arr, 0, arr.length - 1);}public static void sort(int[] arr, int l, int r) {}// 归并排序非递归版public static void mergeSort2(int[] arr) {int n = arr.length;for (int l, m, r, step = 1; step < n; step <<= 1) {l = 0;while (l < n) {m = l + step - 1;if (m + 1 >= n) {break;}r = Math.min(l + (step << 1) - 1, n - 1);merge(arr, l, m, r);l = r + 1;}}}public static void merge(int[] arr, int l, int m, int r) {int i = l;int a = l;int b = m + 1;while (a <= m && b <= r) {help[i++] = arr[a] <= arr[b] ? arr[a++] : arr[b++];}while (a <= m) {help[i++] = arr[a++];}while (b <= r) {help[i++] = arr[b++];}for (i = l; i <= r; i++) {arr[i] = help[i];}}}

在这里插入图片描述

http://www.xdnf.cn/news/13165.html

相关文章:

  • Manus AI 与多语言手写识别
  • 论文笔记:LANGUAGE MODELS REPRESENT SPACE AND TIME
  • 【HarmonyOS 5】鸿蒙CodeGenie AI辅助编程工具详解
  • 1、ZYNQ 开篇简介
  • 向量数据库Milvus在windows环境下的安装
  • SQL进阶之旅 Day 24:复杂业务场景SQL解决方案
  • Unity实现不倒翁
  • Dispatch PDI(DPDI)kettle调度管理平台稳定版本,正式登场!
  • Nuxt + Pinia + Element Plus 后台管理系统搭建教程(含源码)
  • CMake测试find_package()命令的相关原理
  • 10- AI大模型-LangChainV0.3应用(一) - 简介,模型调用,prompt模板,输出解析器
  • 6.10
  • Vue.js 中的 v-bind 指令详解
  • Vue 模板语法之指令语法详解
  • 深入解析 GitHub Token 与 NPM Token:自动化发布的完整指南
  • 医学图像分割最新进展
  • 苹果签名应用掉签频繁原因排查,以及如何避免
  • WebRTC 中 ICE 流程优化:SRS 轻量级部署与 NAT 类型检测实战
  • 项目管理三要素有哪些?如何实现项目管理的三要素平衡
  • 题单:归并排序
  • DSP——时钟树讲解
  • 使用联邦学习进行CIFAR-10分类任务
  • 消防车辆管理系统:为消防公车筑牢安全与效率防线
  • 磐维数据库的权限使用
  • spark数据处理练习题番外篇【下】
  • 统计学核心概念与现实应用精解(偏机器学习)
  • ios 26官宣:car play升级提升车载体验
  • 丝杆升降机的物联网与大数据应用的具体例子
  • React 19 新特性
  • VSCode中PHP使用Xdebug