算法-分治和逆序

分治法(Divide and Conquer)是一种重要的算法设计范式,它通过将复杂的问题分解成更小、更易于管理和解决的子问题,然后递归地解决这些子问题,最后将子问题的解合并以得到原问题的解。分治法通常用于排序、搜索、数学计算和优化等问题。

分治法的核心思想可以概括为三个步骤:

  1. 分解(Divide):将原问题分解为若干个规模较小的相同问题。

  2. 解决(Conquer):递归地解决这些子问题。如果子问题足够小,可以直接解决。

  3. 合并(Combine):将子问题的解合并以得到原问题的解。

时间复杂度
  1. 最佳情况:如果每次分区操作都能将数组均匀地分成两个相等的部分,那么快速排序的时间复杂度是最优的。在这种情况下,递归的深度是 logn(其中 n 是数组的长度),每一层的工作时间是 O(n)。因此,总的时间复杂度是 �(�log⁡�)O(nlogn)。

  2. 平均情况:在大多数情况下,快速排序的性能接近最佳情况,尽管可能不是完全均匀的划分。平均情况下的时间复杂度也是 O(nlogn)。

  3. 最坏情况:如果每次分区操作都极不均匀,例如每次只将数组分成一个元素和其余元素两部分,那么递归的深度将是 �n,每一层的工作时间仍然是 �(�)O(n),但总共有 �n 层。因此,总的时间复杂度是 O(n的平方)。这种情况通常发生在数组已经有序或者完全逆序的情况下。

逆序

2 4 1 3 5

初始化逆序数 count=0;

(2,4)正序

(2,1)逆序,count=1;

(2,3)正序

(2,5)正序

(4,1)逆序,count=2;

(4,3)逆序,count=3;

(1,3)正序

(1,5)正序

(3,5)正序

一般来讲一个一个对照的话,一般就是也就是说这种算法的时间复杂度上限为O(n2)。

但是分治策略,可以降低到nlogn 因此可以直接操作。

对应算法

两个有序的序列 去合并成新序列,并且找到逆序数。

假定分解后的两个序列分别为A,B,(A在前,B在后)已得到A,B的逆序数分别为rA,rB且假定计数完逆序数后把A,B排序为有序序列,以此为基础,得到A,B两序列元素之间的逆序数的合并算法为MAC算法(有(ai,bj)组合,ai来自A,bj来自B,如果有逆序就要计数)。

算法 MAC. 给定两个有序序列A、B,输出它们之间的逆序数和一个合并后有序 的序列C。

MAC1. [初始化变量] 初始化A、B、C的下标i=0,j=0,k=0,和计数值               count=0,初始化C为空序列;

MAC2. [A或B是否没有元素?]if A没有元素 or B没有元素,把有元素 不空的那个序列剩余的元素全部加到C的后面并返回count和C;

MAC3. [是否要增加逆序数?] If A[i]>B[j],count增加的计数值为A中还              有的元素数量,把B[j]从B中移到C的最后面,j←j+1,k←k+1;MAC4. [无需增加逆序数] 把A[i]从A中移到C的最后面,                         i←i+1,k←k+1,回到MAC2。停止的条件就是有一方数组为空 停止全部操作加入到第三个序列
给个例子

例2.2 用MAC算法数一下序列A= {2,4 ,7},B={1,3,5,8}之间的逆序数。

初始化逆序数 i=0,j=0,k=0,count=0,C={};

A[i]>B[j],count=3,A={2,4,7},B={3,5,8},C={1},j=1,k=1;
A[i]<B[j],count=3,A={4,7},B={3,5,8},C={1,2},i=1,k=2;
A[i]>B[j],count=5,A={4,7},B={5,8}C={1,2,3},j=2,k=3;
A[i]<B[j],count=5,A={7},B={5,8}C={1,2,3,4},i=2,k=4;
A[i]>B[j],count=6,A={7},B={8}C={1,2,3,4,5},j=3,k=5;
A[i]<B[j],count=6,A={},B={8}C={1,2,3,4,5,7},i=3,k=6;
C={1,2,3,4,5,7,8},k=7,返回count,C;

最后计数值count=6,C={1,2,3,4,5,7,8}。

但我越来越感觉其实这个需要分治策略时候刚好是分成了两个有序数列。因为只有这样才是所谓mac算法的前提。这样不仅能够求出逆序数,同样的可以使得序列按照顺序排列。

SAC算法

递归算法和分治策略

将一个序列排序并且找到全部逆向序列数

算法 SAC. 给定序列S,输出该序列的的逆序数count和排序后的S

SAC1. [是否分解到基问题?] if S的元素只有1个,count=0,返回count              和S;

SAC2. [分解S]把S分解为两个序列A,B,A是前半,B是后半;

SAC3. [递归] 分别对A、B递归执行SAC算法,即(rA,A)=SAC(A);(rB,B)=SAC(B);SAC4. [合并] 把对A,B执行MAC合并算法,即(r,S)=MAC(A,B);  SAC5. [加总] count←r+rA+rB,返回count,S。
java
package org.com.test;
import java.io.*;
import java.util.*;public class SAC {public static void main(String[] args) {System.out.println("请输入待计数逆序的整数序列(以空格分开,各项值都不同)");Scanner in = new Scanner(System.in);String line = in.nextLine();String[] tokens = line.split(" ");int[] S1 = new int[tokens.length];for (int i = 0; i < tokens.length; i++) {S1[i] = Integer.parseInt(tokens[i]);}int count = sortAndCount(S1);for (int i = 0; i < S1.length; i++) {System.out.print(S1[i] + " ");}System.out.print("\n逆序计数为: " + count);}private static int sortAndCount(int[] S) {if (S.length == 1)return 0;int n = S.length / 2;int[] A = new int[n];int[] B = new int[S.length - n];int j = 0;for (int i = 0; i < A.length; i++)A[i] = S[j++];for (int i = 0; i < B.length; i++)B[i] = S[j++];int rA = sortAndCount(A);int rB = sortAndCount(B);int r = mergeAndCount(A, B, S);return (r + rA + rB);}private static int mergeAndCount(int[] A, int[] B, int[] C) {int i = 0, j = 0, k = 0, count = 0;for (int e: A)System.out.print(e);System.out.println();for (int e: B)System.out.print(e);while (i < A.length && j < B.length) {if (A[i] > B[j]) {count += A.length - i;C[k++] = B[j++];} else {C[k++] = A[i++];}}if (i == A.length && j < B.length)for (int l = j; l < B.length; l++)C[k++] = B[l];if (i < A.length && j == B.length)for (int l = i; l < A.length; l++)C[k++] = A[l];return count;}
}
python
# @Author: K1t0
# @Time: 2024/9/19
# @Description: 分治算法 逆序数# 函数功能: SAC 算法
def SAC(list2):# 递归结束判定条件if len(list2) <= 1:return 0# 分组序列 A ,B Num_A Num_BA=[];B=[]Num_A=len(list2)//2Num_B=len(list2)-Num_Afor i in range(len(list2)):if i<Num_A:A.append(list2[i])else:B.append(list2[i])rA=SAC(A)rB=SAC(B)r=MAC(A,B,list2)return r+rA+rB
# 函数功能:MAC 算法
def MAC(A,B,C):# A B C 下标i=0;j=0;k=0;count=0# A B 逆序判定while i<len(A) and j <len(B):if A[i]>B[j]:count+=len(A)-iC[k]=B[j]j+=1;k+=1else:C[k]=(A[i])i+=1;k+=1# 任何一方 结束,另一方全部加入C的序列中if i==len(A) and j<len(B):for c in range(j,len(B)):C[k]=B[c]k+=1if i<len(A) and j==len(B):for c in range(i,len(A)):C[k]=A[c]k+=1return countif __name__=="__main__":# 接收序列list1=input("Input your list:").split()list2=[int(num) for num in list1 ]print(SAC(list2))print(list2)
一些理解

首先分治算法非常的简单,但是在写代码的时候总是会出现问题,首先就是因为这个参数传递的问题,因为java参数传递是引用传递,但是python传递是通过可变类型传递,因此我们需要传递一个参数进去才能达到引用的效果。

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

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

相关文章

基于STM32F103C8T6单片机的DDS信号源设计

本设计能够输出三角波信号、方波信号和正弦波信号,主要由STM32F103C8T6最小核心板、电源供电电路模块、AD9833电路模块、矩阵按键电路模块、LCD1602液晶显示模块等组成。在设计中&#xff0c;使用STM32F103C8T6作为控制芯片&#xff0c;结合LCD1602液晶显示器&#xff0c;矩阵键…

稳了,搭建Docker国内源图文教程

大家好&#xff0c;之前分享了我的开源作品 Cloudflare Workers Proxy&#xff0c;它的作用是代理被屏蔽的地址&#xff0c;理论上支持代理任何被屏蔽的域名&#xff0c;使用方式也很简单&#xff0c;只需要设置环境变量 PROXY_HOSTNAME 为被屏蔽的域名&#xff0c;最后通过你的…

Unity多语言插件I2 Localization国际化应用

【就不收费了&#xff0c;要个关注不过分吧】 【图片来自插件官网&#xff0c;侵删】 前言 目前游戏往往都不会仅局限于国内语言&#xff0c;为了适应产品都要做国际化适配&#xff0c;因此会用到这个插件&#xff0c;这个插件要付费&#xff0c;因此请前往unity官网进行下载…

秒懂Linux之消息队列与信号量(了解)

目录 前言 消息队列原理 信号量理论 信号量原理 IPC资源 前言 消息队列与信息量目前已经不常用了&#xff0c;大家也可以参考共享内存去了解基本原理即可。 消息队列原理 消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法 每个数据块都被认为是有一个类型&…

mfc140u.dll引发的软件故障怎么破?mfc140u.dll文件损坏的解决办法全知道!

当这个重要的 DLL 文件丢失或损坏时&#xff0c;用户可能会收到一个错误消息&#xff0c;提示 “程序无法启动&#xff0c;因为计算机中缺失 mfc140u.dll” 或类似的提示。这种情况不仅令人困扰&#xff0c;而且可以干扰正常的工作流程&#xff0c;尤其是当您依赖特定软件完成日…

KMP算法的实现

这是C算法基础-数据结构专栏的第二十六篇文章&#xff0c;专栏详情请见此处。 引入 KMP算法是一种可以快速查找某一字符串在一个文本中的所有出现的算法。 下面我们就来讲KMP算法的实现。 定义 Knuth–Morris–Pratt 算法&#xff0c;简称KMP算法&#xff0c;是由Knuth、Pratt…

基于VUE的教师教学质量网络评测评价统计分析系统

1、 选题的背景与意义 21世纪是信息化的世纪&#xff0c;我们的一些生活习惯因为计算机而发生改变&#xff0c;我们也逐渐习惯于通过计算机的各项功能来获得便利。这其中所带来的挑战和机遇为各行业的发展指明了一个方向。教学质量评测是一项琐碎而又十分细致的工作&#xf…

【永磁同步电机(PMSM)】 3. 基于Matlab 的仿真与控制

【永磁同步电机&#xff08;PMSM&#xff09;】 3. 基于Matlab 的仿真与控制 1. 电机的仿真与控制2. BLDC 电机与 PMSM 电机3. BLDC 的方波控制4. 磁场定向控制&#xff08;FOC&#xff09;5. 空间矢量调制 (SVM)6. PMSM 模型的频率响应估计 电机仿真和控制是能源生产、汽车、航…

Java对象一口气讲完!φ(* ̄0 ̄)

Java Object类 Java面向对象设计 - Java Object类 Java在java.lang包中有一个Object类。 所有Java类都直接或间接扩展Object类。 所有Java类都是Object类的子类Object类是所有类的超类。 Object类本身没有超类。 Object类的引用变量可以保存任何类的对象的引用。 以下代…

OSPFv3协议几类LSA介绍

OSPFv3协议介绍 与OSPFv2相比&#xff0c;OSPFv3在工作机制上与OSPFv2基本相同&#xff1b;但为了支持IPv6地址格式&#xff0c;OSPFv3对OSPFv2做了一些改动。OSPFv3基于OSPFv2基本原理增强&#xff0c;是一个独立的路由协议&#xff08;v3不兼容v2&#xff09;协议号仍然是89…

竹云赋能“中国·贵州”全省统一移动应用平台建设,打造政务服务“新引擎”

近日&#xff0c;2024中国国际大数据产业博览会在贵州贵阳圆满落幕。会上&#xff0c;由贵州省政府办公厅牵头建设的“中国贵州”全省统一移动应用平台正式发布&#xff0c;聚焦民生办事、政务公开、政民互动、扁平高效、数据赋能五大模块&#xff0c;旨在打造公平普惠的服务平…

Hbase操作手册

一&#xff1a;Hbase 创建数据库表 1.进入hbase shell 2.创建数据库表的命令&#xff1a;create 表名, 列族名1,列族名2,列族名N 3.如果想查看所有数据库表&#xff0c;可以使用list 命令&#xff1a; 4.可以看到&#xff0c;刚创建的数据库表user 已经在数据库表的列表中&…

单元格左边放文字右边放按钮

1 . 代码 /* 添加到你的CSS文件中 */ .switch-td { display: flex; justify-content: space-between; /* 两端对齐&#xff0c;这样文本和开关会分别靠左和靠右 */ align-items: left; /* 垂直居中 */ } /* 如果你不想改变其他<td>的默认左对齐&#xff0c;…

TTF与图片之间的相互转换,使用python,potrace,fontforge

概述 TTF是字体文件格式&#xff0c;里面存储的是矢量化的字体信息。TTF与图片之间的相互转换简单描述如下&#xff1a; 使用python中的PIL&#xff08;pillow&#xff09;图像库可以实现TTF转图片使用potrace可以将图片转为矢量文件svg&#xff0c;再进一步使用fontforge可以…

一天认识一个硬件之连接线

我们在日常工作生活中经常会用到许多连接线&#xff0c;比如视频线&#xff0c;USB线&#xff0c;但是他们的区别在哪里&#xff0c;可能太不清楚&#xff0c;今天就来给大家分享一下。 HDMI线 特点&#xff1a;HDMI线是一种全数字化视频和声音发送接口&#xff0c;可以发送未…

phpword读取word docx文档文本及图片转html格式

最近在做一个PHP读取word文档功能&#xff0c;搜索一圈后决定选择用phpword第三方组件。 composer安装phpWord composer require phpoffice/phpword如果你的文件是doc格式&#xff0c;直接另存为一个docx就行了&#xff1b;如果你的doc文档较多&#xff0c;可以下一个批量转…

Lingo求解器基本语法

Lingo是一款用于线性规划和整数规划的数学建模和求解软件&#xff0c;被广泛应用于运筹学、生产优化、供应链管理等领域。今天与大家一起来熟悉一下它的基本语法 Lingo基本语法 1、定义目标函数为MIN&#xff0c;MAX. 2、以一个分号“&#xff1b;”结尾。除SETS,ENDSETS,D…

煤矸石检测数据集(yolo)

yolo煤矸石检测 数据集 pt模型 界面&#xff0c; ✓3091张图片和txt标签&#xff0c;标签类别两类&#xff1a;“coal”、“rock”。 ✓适用于煤矸石识别&#xff0c;深度学习&#xff0c;机器学习&#xff0c;yolov5 yolov6 yolov7 yolov8 yolov9 yolov10&#xff0c;Python 煤…

Nvidia的高级研究科学家Jim Fan预计在未来两到三年内,机器人技术将取得重大进展

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Wacom 和 Splashtop 携手共赴 IBC 2024 展会,宣布向欧洲市场隆重推出 Wacom Bridge

2024年9月10日 荷兰阿姆斯特丹&德国杜塞尔多夫 Wacom 是数位笔技术的全球领袖&#xff0c;Splashtop 是高性能远程访问解决方案领域的先驱&#xff0c;双方宣布已在欧洲隆重推出 Wacom Bridge&#xff0c;目前 Splashtop Enterprise 和 Splashtop Business Access Perform…