递归行为与归并排序

news2024/11/24 3:47:03

 master公式  T(N)=a*T(N/b)+O(N^d)        

        T(N):问题的规模是N个数据

        N/b:子过程的规模

        a:调用的次数

        O(N^d)  :除子问题的调用之外,剩余的代码的时间复杂度

使用条件:满足子问题等规模的递归

arr[L,R]范围上求最大值
public class GetMax {
    @Test
    public void test() {
        int[] arr = new int[]{3,4,1};//StackOverflowError栈溢出
        System.out.println(getMax(arr));
    }

    public static int getMax(int[] arr) {
        return process(arr, 0, arr.length - 1);
    }

    //    arr[L,R]范围上求最大值
    public static int process(int[] arr, int L, int R) {
        if (L == R) {  //数组元素只有一个时,直接返回
            return arr[L];
        }
        int mid = L + (R - L) >> 1;//中点

        int leftMax = process(arr, L, mid);
        int rightMax = process(arr, mid + 1, R);
        return Math.max(leftMax, rightMax);
    }
}

归并排序

将整组数组分为左右两组分别排序,两边分别排好序之后整合成一整个有序数组

整合左右两侧有序数组

指针先指向两数组第一个位置,指针所在的数比较大小

较小值拷贝到新开辟的数组中,当前数组指针后移

较大值指针保持不变,等待另一指针移动后与新的值进行比较

直到有一边的指针越界,将另一数组的剩下所有的数拷贝到新数组中

public class MergeSort {
    @Test
    public void test(){
        int[] arr = new int[]{3,1,2};
        MergeSort.mergeSort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }
    public static int[] mergeSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return arr;
        }
        MergeSort.process(arr, 0, arr.length - 1);
        return arr;
    }

    public static void process(int[] arr, int L, int R) {
        if (L == R) {
            return;
        }
        int mid = L + (R - L) >> 1;
        MergeSort.process(arr, L, mid);//左数组排序
        MergeSort.process(arr, mid + 1, R);//右数组排序
        MergeSort.merge(arr, L, mid, R);//整合
    }

    //整合
    public static void merge(int[] arr, int L, int mid, int R) {
        int[] help = new int[R - L + 1];//开辟一块等区域的新数组,用来拷贝
        int i = 0;//新数组的指针
        int p1 = L;//左数组的指针
        int p2 = mid + 1;//右数组的指针
        while (p1 <= mid && p2 <= R) {//左右两边的数组都没有越界
            if (arr[p1] <= arr[p2]) {//将较小的数拷贝至help数组
                help[i++] = arr[p1++];
            } else {
                help[i++] = arr[p2++];
            }
        }
        while (p1 > mid && p2 <= mid) {//p1指针首先越界,将p2所在数组剩余的数拷贝到help数组
            help[i++] = arr[p2++];
        }
        while (p2 > R && p1 <= mid) {//p2首先越界,将p1所在数组剩余的数拷贝到help数组
            help[i++] = arr[p1++];
        }

        for (int j = 0; j < help.length; j++) {
            arr[L + j] = help[j];
        }
    }
}

归并排序的时间空间复杂度

小和问题 —— 可以利用归并排序边排序边计算小和,可以将O(n^2)转化为O(NlogN)的复杂度

暴力求解:每经过一个数遍历左边的数,比它本身小就加上  -->   时间复杂度:O(N^2)

左边比n小的数相加  等效于  右边比n大的个数*n

用归并排序求解的时候,左侧的数小才产生小和,右侧的数小不产生小和

合并的时候只看右侧是否有比左侧的数大,有则计算此次合并时所要加的小和值,没有则左侧的指针右移

在两侧指针指向的数相等时,一定是右侧的指针右移

如果左侧的指针右移,左侧指针指向的数大,右侧指针指向的数小,不产生小和,此时就会导致小和漏算

public class SmallSum {
    @Test
    public void test() {
        int[] arr = new int[]{2, 1, 3};//3
        System.out.println(SmallSum.smallSum(arr));
    }

    public static int smallSum(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;
        }

        int mid = L + (R - L) >> 1;
        return process(arr, L, mid) + process(arr, mid + 1, R) + merge(arr, L, mid, R);
        //左数组的小和+右数组的小和+两数组merge后的小和
    }

    public static int merge(int[] arr, int L, int mid, int R) {
        int help[] = new int[R - L + 1];
        int i = 0, p1 = L, p2 = mid + 1;
        int smallnum = 0;
        while (p1 <= mid && p2 <= R) {//都没越界
            if (arr[p1] < arr[p2]) {
                smallnum = smallnum + arr[p1] * (R - p2 + 1);
                //整合时两数组都有序,当arr[p1]<arr[p2]时,那么arr[p1]一定也小于arr[p2]后的所有数,计算出小和需要加多少次arr[p1]即可
                help[i++] = arr[p1++];
            } else {//如果左右两数组指针指向的数值相同时,一定是右数组的指针右移,拷贝右数组的数并且不产生小和
                //相等时如果拷贝左数组,可能会导致漏算
                //右侧小的时候时候不产生小和
                help[i++] = arr[p2++];
            }
        }
        //小和算完,拷贝剩余数组(不拷贝也可以)
//        while (p2 > R && p1 <= mid) {
//            help[i++] = arr[p1++];
//        }
//        while (p1 > mid && p2 <= R) {
//            help[i++] = arr[p2++];
//        }
        return smallnum;
    }
}

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

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

相关文章

49天精通Java,第27天,队列、双端队列、优先队列

目录 一、队列与双端队列二、Queue和Deque三、api对比1、add和offer区别2、remove和poll3、element和peek 四、优先队列1、PriorityQueue常用方法2、ArrayDeque常用方法 大家好&#xff0c;我是哪吒。 一、队列与双端队列 双端队列是一种特殊的队列&#xff0c;它的两端都可以…

吴军《计算之魂》读后感

前言 断断续续&#xff0c;终于完成了这本书的第一次通读&#xff0c;记录下自己的一些想法。 先说一个小故事。前段时间家里买了一个小鱼缸&#xff0c;问我有没有办法让水自动循环&#xff0c;但不想用电。没有好的想法&#xff0c;去小某书上搜了下&#xff0c;好多案例教…

【哈士奇赠书活动 - 18期】-〖Flask Web全栈开发实战〗

文章目录 ⭐️ 赠书活动 - 《Flask Web全栈开发实战》⭐️ 编辑推荐⭐️ 内容提要⭐️ 赠书活动 → 获奖名单 ⭐️ 赠书活动 - 《Flask Web全栈开发实战》 内容简介&#xff1a; 《Flask Web全栈开发实战》围绕 Flask 框架&#xff0c;详细地讲解了使用 Flask 开发网站的各项技…

vue2项目中使用本机图片的一些问题

前后端分离项目&#xff0c;&#xff08;vue2springboot2.6.3) 前端上传图片&#xff0c;后端将图片保存在本地。当前端使用上传的图片时出现的一些问题说明。 前端上传图片文件&#xff0c;后端接收到图片文件后将图片保存到vue项目的src/assets/club目录下&#xff0c;如下…

VMware vSphere Replication 8.7 (for vSphere 8.0U1) - 虚拟机复制和数据保护

请访问原文链接&#xff1a;https://sysin.org/blog/vmware-vsphere-replication-8/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 新增功能 vSphere Replication 8.7 | 2023 年 4 月 18 日 | 内部版本 21591677 vSphere Re…

GPT4.0+Midjourney=最佳组合,简单玩法

以下是我设计的一个简单的组合玩法&#xff0c;操作如下&#xff1a; 问gpt4: Here is a MidJourney Prompt Formula: A detailed image of [Subject] [doing something interesting] during [time of day], taken with a [type of camera], using [type of lens] with cinema…

ChatGPT会对我们日常生活带来什么影响?这些技术会改变我们学习阅读工作方式吗?

ChatGPT会对我们日常生活带来什么影响&#xff1f;这些技术会改变我们学习阅读工作方式吗&#xff1f; AI 这个话题很火&#xff0c;我也一直在关注着&#xff0c;很多人甚至觉得 AI 会改变世界&#xff0c;也许你会好奇&#xff1a;ChatGPT 会在三年内终结编程吗&#xff1f;A…

基于gitlab搭建Drone CI

drone简介&#xff1a; drone官方文档&#xff1a;https://docs.drone.io/ drone跟Jenkins一样&#xff0c;可实现持续集成&#xff0c;就是可以帮助我们解决重复的代码构建&#xff0c;自动化测试&#xff0c;发布等重复劳动&#xff0c;通过简单一个提交代码的动作&#xff…

Text-to-3D 任务论文笔记: Latent NeRF

文章目录 概述相关工作3D形状合成使用2D监督的text-to-3D 任务 方法前置知识LDMScore Distillation Latent NeRF文本引导RGB refinementSketch-Shape Guidance对于显式形状的Latent-Paint 实验实验细节文本引导的生成RGB RefinementTextual-Inversion Sketch-Shape GuidanceLat…

使用Handler创建一个Android秒表应用

0、应用是一个有活动、布局和其他资源组成的集合。其中一个活动是应用的主活动。每个应用都有一个主活动&#xff0c;在文件AndroidManifest.xml中指定。 1、默认地&#xff0c;每个应用都在自己的进程中运行。这样有助于保证应用安全。 2、但是可以使用startActivity(intent)传…

信息安全支撑技术

信息安全支撑技术 密码学密码学发展古典密码近代密码学现代密码学 基本保密通信模型密码系统的安全性密码学技术在信息安全中的应用对称密码算法非对称密码算法其他密码服务哈希函数消息认证码数字签名 公钥基础设施&#xff08;PKI&#xff09;CA&#xff1a;认证权威RA&#…

九耶丨阁瑞钛伦特-SpringCloud(六)

Spring Cloud Config 是一个基于 Spring Boot 实现的分布式配置管理工具&#xff0c;它专注于管理各种环境中的应用程序配置&#xff0c;例如开发环境、测试环境和生产环境等。它提供了一个集中的配置服务器&#xff0c;允许在运行时动态地管理和更新应用程序的配置信息&#x…

10 个超赞的 C 语言开源项目

今天给大家分享10个超赞的C语言开源项目&#xff0c;希望这些内容能对大家有所帮助&#xff01; 01 Webbench Webbench是一个在 Linux 下使用的非常简单的网站压测工具。 它使用fork()模拟多个客户端同时访问我们设定的URL&#xff0c;测试网站在压力下工作的性能。 最多可以…

Unity版本使用情况统计(更新至2023年4月)

本期UWA发布的内容是第十二期Unity版本使用统计&#xff0c;统计周期为2022年11月至2023年4月&#xff0c;数据来源于UWA网站&#xff08;www.uwa4d.com&#xff09;性能诊断提测的项目。希望给Unity开发者提供相关的行业趋势&#xff0c;了解近半年来哪些Unity版本的使用概率更…

Java经典笔试题—day05

Java经典笔试题—day05 &#x1f50e;选择题&#x1f50e;编程题&#x1f95d;统计回文&#x1f95d;连续子数组最大和 &#x1f50e;结尾 &#x1f50e;选择题 (1)下面的程序 编译运行后&#xff0c;在屏幕上显示的结果是&#xff08;&#xff09; public class Test {publi…

使用敏捷开发工具做敏捷需求管理流程

上一篇我们介绍了如何管理产品路线图&#xff0c;这一篇我们介绍下如何管理产品Backlog。 史诗故事通常都是比较大的故事&#xff0c;所以我们需要将史诗故事规划到产品Backlog中&#xff0c;以便让团队在产品Backlog中对史诗故事进行拆分&#xff0c;将其拆解为更小的用户故事…

Kubernetes对象之PersistentVolume,PersistentVolumeClaim和StorageClass

前面我们学习了Kubernetes中的Volume&#xff0c;我们可以发现前文中的Volume&#xff08;无论何种类型&#xff09;和使用它的Pod都是一种静态绑定关系&#xff0c;在Pod定义文件中&#xff0c;同时定义了它使用的Volume。在这种情况下&#xff0c;Volume是Pod的附属品&#x…

linux安装redis服务

linux环境采用centos7 1.下载redis安装包 官网下载地址&#xff1a;https://redis.io/download/ 2.安装redis依赖 yum install -y gcc tcl3.上传安装包并解压 tar -xzf redis-6.2.12.tar.gz4.编译安装 进入目录下并安装 cd redis-6.2.12 make && make install默认…

Python 密码破解指南:15~19

协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【OpenDocCN 饱和式翻译计划】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 收割 SB 的人会被 SB 们封神&#xff0c;试图唤醒 SB 的人是 SB 眼中的 SB。——SB 第三定律 十五、…

基于springboot会员制医疗预约服务管理信息系统

开发技术介绍 Java语言简介 Java是由SUN公司推出&#xff0c;该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称&#xff0c;也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具备了显著的优势和广阔的前景&#xff…