分治---归并排序

news/2024/10/19 10:25:41

参考资料

水平有限,欢迎交流!
【如何优雅地排序——3分钟看懂【归并排序】的基本思想】

练习题

P1177 【模板】排序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
LCR 170. 交易逆序对的总数 - 力扣(LeetCode)

关键步骤与应用

步骤

在归并过程中,主要包含两个关键步骤:

  1. 分割(Divide):将数组递归地分成两个或多个子数组。
  2. 合并(Merge):将两个或多个已排序的子数组合并成一个有序的大数组。

应用

可用于求逆序对的对数(力扣LCR 170)

归并排序

P1177 【模板】排序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;public class Main {static int N;static int[] arr;static int[] tmp;//分割static void MergeSort(int[] a, int l, int r) {if (l >= r) {return;}int mid = (l + r) >> 1;MergeSort(a, l, mid);MergeSort(a, mid + 1, r);merge(a, l, mid, r);}//合并static void merge(int[] a, int l, int mid, int r) {int i = l, j = mid + 1, k = 0;// 合并两个已排序的子数组while (i <= mid && j <= r) {if (a[i] <= a[j]) {tmp[k++] = a[i++];} else {tmp[k++] = a[j++];}}// 处理剩余的元素while (i <= mid) {tmp[k++] = a[i++];}// 将临时数组中的元素复制回原数组for (int x = 0; x < k; x++) {a[l+x] = tmp[x];}}public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));N = Integer.parseInt(in.readLine());arr = new int[N];tmp = new int[N];String[]line = in.readLine().split(" ");for (int i = 0; i < N; i++) {arr[i] = Integer.parseInt(line[i]);}MergeSort(arr, 0, N - 1);for (int i : arr) {out.write(i + " ");}out.flush();in.close();out.close();}
}

求逆序对对数(仅考虑思路,不考虑消耗)

LCR 170. 交易逆序对的总数 - 力扣(LeetCode)

class Solution {int []tmp;int mergeSort(int []nums,int l,int r){if(l>=r)return 0;int cnt = 0;int mid = l +r >>1;cnt+=mergeSort(nums, l, mid);cnt+=mergeSort(nums, mid+1, r);int i = l,j = mid +1 ,k = 0;while(i<=mid&&j<=r){if(nums[i]<=nums[j]){tmp[k++] = nums[i++];}else{cnt+=(mid-i+1);tmp[k++] = nums[j++];}}while(i<=mid){tmp[k++] = nums[i++];}for(int x = 0;x<k;x++){nums[x+l] = tmp[x];}return cnt;}public int reversePairs(int[] record) {tmp = new int[record.length];return mergeSort(record, 0, record.length-1);}
}

3193. 统计逆序对的数目 - 力扣(LeetCode)
下面为暴力写法,过一半左右

import java.util.ArrayList;
import java.util.List;class Solution {final int mod = 1000000007;List<List<Integer>> ans;int[] tmp;boolean[] vis;// 调整mergeSort方法以正确计算逆序对int mergeSortAndCount(List<Integer> cur, int l, int r) {if (l >= r) return 0;int mid = (l + r) >> 1;int count = 0;count += mergeSortAndCount(cur, l, mid);count += mergeSortAndCount(cur, mid + 1, r);count += mergeAndCount(cur, l, mid, r);return count;}int mergeAndCount(List<Integer> cur, int l, int mid, int r) {int i = l, j = mid + 1, k = 0;int count = 0;while (i <= mid && j <= r) {if (cur.get(i) <= cur.get(j)) {tmp[k++] = cur.get(i++);} else {tmp[k++] = cur.get(j++);count += (mid - i + 1);  // 确定逆序对的个数}}while (i <= mid) {tmp[k++] = cur.get(i++);}for (i = 0; i < k; i++) {cur.set(l + i, tmp[i]);}return count;}void dfs(int[] nums, List<Integer> res, int[][] requirements) {int len = nums.length;if (res.size() == len) {// 判断所有的要求是否都满足boolean isValid = true;for (int[] req : requirements) {int end = req[0];int cnt = req[1];List<Integer> sublist = new ArrayList<>(res.subList(0, end + 1));tmp = new int[sublist.size()];int inversionCount = mergeSortAndCount(sublist, 0, end);if (inversionCount != cnt) {isValid = false;break;}}if (isValid) {ans.add(new ArrayList<>(res)); // 只有满足所有要求时才添加到结果集}return;}for (int i = 0; i < len; i++) {if (!vis[i]) {vis[i] = true;res.add(nums[i]);dfs(nums, res, requirements);res.remove(res.size() - 1);vis[i] = false;}}}public int numberOfPermutations(int n, int[][] requirements) {ans = new ArrayList<>();int[] nums = new int[n];for (int j = 0; j < n; j++) {nums[j] = j;}vis = new boolean[n];dfs(nums, new ArrayList<>(), requirements);return ans.size() % mod;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode 1135. 最低成本连通所有城市

1.题目基本信息 1.1.题目描述 想象一下你是个城市基建规划者,地图上有 n 座城市,它们按以 1 到 n 的次序编号。 给你整数 n 和一个数组 conections,其中 connections[i] = [x_i, y_i, cost_i] 表示将城市 x_i 和城市 y_i 连接所要的cost_i(连接是双向的)。 返回连接所有城…

Leetcode 1129. 颜色交替的最短路径

1.题目基本信息 1.1.题目描述 给定一个整数 n,即有向图中的节点数,其中节点标记为 0 到 n – 1。图中的每条边为红色或者蓝色,并且可能存在自环或平行边。 给定两个数组 redEdges 和 blueEdges,其中:redEdges[i] = [a_i, b_i] 表示图中存在一条从节点 a_i 到节点 b_i 的红…

Linux系统命令3

1、df 查看磁盘使用情况Filesystem:代表该文件系统时哪个分区,所以列出的是设备名称。 1K-blocks:说明下面的数字单位是1KB,可利用-h或-m来改变单位大小,也可以用-B来设置。 Used:已经使用的空间大小。Available:剩余的空间大小。 Use%:磁盘使用率。如果使用率在90%以上…

线性表学习1

线性结构 若结构是非空有限集,则有且仅有一个开始结点和一个终端结点,并且除了首尾节点外所有结点都最多只有一个直接前趋和一个直接后继。 可表示为:(a1,a2,a3,...) 特点:只有一个首结点和尾结点 本质特征:除首尾结点外,其他结点只有一个直接前驱和一个直 接后继。 简言…

学习 gradle 基础

简介 Gradle 的优势一款最新的,功能最强大的构建工具,用它逼格更高 使用 Groovy 或者 Kotlin 代替 XML,使用程序代替传统的 XML 配置,项目构建更灵活 丰富的第三方插件,让你随心所欲使用 完善 Android,Java 开发技术体系下载和安装 官网地址 https://services.gradle.org…

AutoResetEvent双向信号(生产者和消费者)例子

AutoResetEvent是一个非常有用的线程同步机制,尤其是在处理生产者和消费者问题的时候,尤其适用。本随笔记录下生产者和消费者一对一问题的两种写法并进行代码执行逻辑的分析,来加深对AutoResetEvent的理解。 写法一:internal class Program {public static AutoResetEvent …

数据采集和融合技术作业1

作业① 1)用requests和BeautifulSoup库方法定向爬取给定网址的数据,屏幕打印爬取的大学排名信息。 a、主要代码解析 该函数从获取的JSON数据中提取前 num 名大学的信息,并将这些信息存储到 ulist 列表中,同时格式化输出这些大学的排名信息 def printUnivList(ulist, html, …

沃顿商学院商业人工智能笔记-六-

沃顿商学院商业人工智能笔记(六) P46:12_简介.zh_en - GPT中英字幕课程资源 - BV1Ju4y157dK 嗨,我是迈克尔罗伯茨。我是威廉H罗伯茨教授。 我是宾夕法尼亚大学沃顿商学院的金融学劳伦斯教授。 在这一系列视频中,我们将讨论金融、机器学习。以及人工智能。因此,当我想到金…