归并排序(三)小和问题

  • 前言
  • 小和
    • 思考
      • 暴力
      • 引申
    • 思路
    • 代码
      • 注意

前言

  上篇博客学习了归并排序,一种是遍历的方式实现,一种是迭代的方式实现,那么归并排序的思路只能用于排序嘛?也不是,这篇博客就记录一下归并排序对于求小和问题的思路与写法。

小和

  在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。假设有这样一个数组 [3,4,1,5,2] 求这个数组的小和是多少?

  按照小和的定义:

  • 3:左侧没有比3小的数,没有小和。
  • 4:左侧有一个3比4小,有小和 3 。
  • 1:左侧没有比1小的数,没有小和。
  • 5:左侧有3、4、1比5小,有小和3+4+1 。
  • 2:左侧有一个1比2小,有小和 1 。
  • 数组的小和:3+3+4+1+1=12 。

思考

暴力

   循环整个数组,依次左侧小于当前值的数累加起来。


引申

  暴力循环可以解决问题,但每次都要从头再次循环判断,性能有点低啊,有没有什么方法可以避免呢?先找一下规律吧。

  • 3:比4小统计了一次,比5小统计了一次,总共统计了2次
  • 4:比5小,统计了1次
  • 1:比5小统计了一次,比2小统计了一次,总共统计了2次
  • 5:右侧没有更大的了
  • 2:右侧没有更大的了

  这个有点眼熟啊,3跟4比,1跟5比,3和4 跟 1和5 比,上篇博客的合并merge 好像可以用上啊,上面的这个数组弄的不好,3、4有序了,1、5有序了,重新弄个数组说明吧:

  • 3:无
  • 2:无
  • 4:3+2
  • 1:无
  • 5:3+2+4+1
  • 6:3+2+4+1+5
  • 3:2+1
  • 0:无
  • (3+2)+(3+2+4+1)+(3+2+4+1+5)+(2+1)= 33
  • 3个1、4个2、3个3、2个4、1个5

按照merge的思路:

第一次操作产生了:5

第二次操作产生了:2+3

第三次操作产生了:1+1+1+2+2+2+3+3+4+4

总结:5+(2+3)+(1+1+1+2+2+2+3+3+4+4)= 33

3个1、4个2、3个3、2个4、1个5

和暴力解析一致,啊哈,这种迭代排序不必暴力循环快多了。

思路

  merge有实现小和的可能,可是该怎么实现呢?合并就不再画图了,直接说思路:

  • 固定流程:左组和右组比较,左数小于右数,记录一次左数
  • 我需要一个数ans记录本次小和。
  • 我需要一个返回值,返回merge小和。
  • 我需要递归操作累加小和,merge返回的小和每次都要参加运算。

代码

 public static int smallSum(int[] arr) {if (arr == null || arr.length < 2) {return 0;}return splitSorting(arr, 0, arr.length - 1);}public static int splitSorting(int[] arr, int l, int r) {// 递归终止条件if (l == r) {return 0;}int m = (l + r) / 2;// 对于左侧来说,l到中点// 对于右侧来说,中点+1到右侧return splitSorting(arr, l, m) + splitSorting(arr, m + 1, r) + merge(arr, l, m, r);}// 我需要一个返回值返回小和public static int merge(int[] arr, int L, int M, int R) {// 我需要一个数组存放数据int[] narr = new int[R - L + 1];// 我需要三个指针,分别指向三个数据的头int i = 0;int p1 = L;int p2 = M + 1;// 我需要一个循环体,结束条件是其中一个越界了,这里写的是循环条件哦,不是结束条件// p1,p2都在各自的范围内// 我需要一个ans记录小和int ans = 0;while (p1 <= M && p2 <= R) {ans += arr[p1] < arr[p2] ? (R - p2 + 1) * arr[p1] : 0;narr[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];}// p1 越界,p1添加完了,剩下数据的就是p2while (p2 <= R) {narr[i++] = arr[p2++];}// p2 越界,p2添加完了,剩下数据的就是p1while (p1 <= M) {narr[i++] = arr[p1++];}// 合并后的narr数据,要放到原来的数组arr里的for (int j = 0; j < narr.length; j++) {// L为左侧数据的开始,从L开始放数据arr[L + j] = narr[j];}return ans;}

注意

  上面的代码不完全是和上次一样的,特别需要提示一个地方,上次写的合并代码中,这个位置是小于等于,而本次的合并代码中,这个位置是小于,区别在于

  • 上次的重点在排序,相等了谁前谁后没关系。
  • 这次的重点在求和,只要小于的,相等的不能再加进去交换了。

【好记性不如烂笔头】排序算法之归并排序(三)小和问题相关推荐

  1. 好记性不如烂笔头——Vite篇

    茶已备好,只待君来!感谢关注 前端点线面 (>‿<),本号定期推荐原创深度好文,帮助每一位在前端领域打拼的伙伴们走向前列,此外关注我获取最前沿知识点.海量学习资料.<前端百题斩> ...

  2. 好记性不如烂笔头——C++篇

    大家好,我是前端点线面,毕业于华中科技大学,非科班出身的一枚新时代农民工,现在是百度前端研发工程师,著有<前端百题斩>.数十篇学习思维导图(go.React.Redux.Vue.Vuex. ...

  3. 好记性不如烂笔头——Vuex篇

    俗话说的好"好记性不如烂笔头",今天秉承着后期复习方便的态度,整理了一份Vuex基础知识点,并以思维导图的方式呈现出来,方便跟老铁们一起查漏补缺. Vuex.png 一.基础 1. ...

  4. 排序算法:归并排序、快速排序

    相关博客: 排序算法:冒泡排序.插入排序.选择排序.希尔排序 排序算法:归并排序.快速排序 排序算法:桶排序.计数排序.基数排序 排序算法:堆排序 十大排序算法小结 一.归并排序: 1.工作原理: 归 ...

  5. 排序算法之--归并排序(好玩的一个算法o。o)快速入门

    排序算法之--归并排序(好玩的一个算法o.o) 下面是归并操作的基本思路(注意:是归并操作哦,不是归并排序哦) 归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存 ...

  6. NOI提高级:排序算法之归并排序、快速排序

    图解排序算法(四)之归并排序 图解排序算法(四)之归并排序 - dreamcatcher-cx - 博客园 小学生图解排序算法:⑥归并排序 小学生图解排序算法:⑥归并排序_纯文笔记-CSDN博客_图解 ...

  7. [Alg]排序算法之归并排序

    [Alg]排序算法之归并排序 作者:屎壳郎 miaosg01@163.com 日期:Aug 2021 版次:初版 简介: 归并排序是一类在任何情况下都能保证Nlg⁡(N)N\lg(N)Nlg(N)的排 ...

  8. 【排序算法】归并排序(C语言)

    [排序算法]-- 归并排序(C语言) 目录 一.归并排序的原理 二.两个有序数组排序和合并 1. 原地排序 2. 创建临时空间 二.递归实现 三.非递归实现 1. 实现思路 2. 数组边界问题 3. ...

  9. 好记性不如烂笔头之 App widgets(二)

    好记性不如烂笔头之 App widgets(一)_禽兽先生不禽兽的博客-CSDN博客 之前记录了 AppWidgets 的基本用法,当我的小组件中需要展示列表的时候,发现它的方式也跟普通的列表控件不一 ...

  10. 涨知识!华为备忘录还能这样玩,难怪古人说好记性不如烂笔头

    涨知识!华为备忘录还能这样玩,难怪古人说"好记性不如烂笔头" 古人云:"好记性不如烂笔头!"这句话是我们从小一直听到大的,可是真的能够做到的,真的没有几位,毕竟 ...

最新文章

  1. 每日一皮:当产品经理试图让程序员冷静下来的时候...
  2. Qt中的QWidget
  3. 定制android触控平板,Adobe发表六款Android平板用触控Apps,一套六款的工具组合
  4. 手动创建DataTable并绑定gridview
  5. java中var是什么意思_js中的var是什么意思
  6. 关于分布式计算的一些概念
  7. C语言 单链表查找出倒数第,查找单链表倒数第k个元素
  8. *.sln和*.suo文件的作用
  9. 基于SSM的Java图书管理系统
  10. 网络安全课第二节 XSS漏洞检测防御
  11. 2022年信息安全工程师考试知识点:网络安全需求分析与基本设计
  12. STM32F407 USB CDC调试与经验总结
  13. 【千锤百炼Python—14】:修改图片格式
  14. 利用DirectShow开发C#版的MP3播放器(二)
  15. [整理]Mac安装Meld,并使用Meld作为git diff tool的工具
  16. python如何连redis_python连接redis的方法
  17. 主流计算机戴尔笔记本电脑,主流价位好机器 戴尔灵越一体机23 5348
  18. 宝峰对讲机16频率表_宝峰uv5r系列对讲机出厂预置频率表-手工编辑版
  19. Linux 下wifi 驱动开发(一)—— WiFi基础知识解析
  20. PAT-2019年冬季考试-乙级-7-3String复读机

热门文章

  1. 吉林大学软件学院软构件与中间件JavaEE实验
  2. 轮廓线DP(插头DP 裸 经典骨牌)
  3. vue3项目实战的请求接口问题(一)跨域问题+解决方法
  4. 不能面对的问题还是在逃避
  5. python中的递归函数如何表示_python:递归函数
  6. Java 使用Tailer类监听文件
  7. 小程序选择手机图片后 压缩图片 转码base64
  8. 【BiSeNet】《BiSeNet:Bilateral Segmentation Network for Real-time Semantic Segmentation》
  9. 乌镇论剑:张朝阳的四张牌=两横两纵
  10. 医疗电子方案——血压计方案