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

科技文化网站建设方案三亚旅游网站策划书

科技文化网站建设方案,三亚旅游网站策划书,做网站和做阿里巴巴,上海企业网站建设补贴前言 算法是程序的灵魂,一个优秀的程序是可以在海量的数据中,仍保持高效计算。目前各大厂的面试要求也越来越高,算法肯定会要去。如果你不想去大厂,只想去小公司,或许并不需要要求算法。但是你永远只能当一个代码工人&…

前言

算法是程序的灵魂,一个优秀的程序是可以在海量的数据中,仍保持高效计算。目前各大厂的面试要求也越来越高,算法肯定会要去。如果你不想去大厂,只想去小公司,或许并不需要要求算法。但是你永远只能当一个代码工人,也就是跟搬砖的没区别。可能一两年后你就会被淘汰。 如果不想永远当个代码工人,就在业余时间学学数据结构和算法。

今天就来分享一个朋友阿里四面挂了的排序算法题912. 排序数组, 排序数组这道题本身是没有规定使用什么排序算法的,但面试官指定需要使用归并排序算法来解答,肯定是有他道理的。

我们知道,排序算法有很多,大致有如下几种:

其中归并排序应该是使用得最多的几种之一,Java中Arrays.sort()采用了一种名为TimSort的排序算法,就是归并排序的优化版本。归并排序自身的优点有二,首先是因为它的平均时间复杂度低,为O(N*logN);其次它是稳定的排序,即相等元素的顺序不会改变;除了这两点优点之外,其蕴含的分治思想,是可以用来解决我们许多算法问题的,这也是面试官为什么要指定归并排序的原因。好了,废话不多说,我们接下来具体看看归并排序算法是如何实现的吧。

归并排序(递归版)

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治策略,即分为两步:分与治。

1. 分:先递归分解数组成子数组

2. 治:将分阶段得到的子数组按顺序合并

我们来具体看看例子,假设我们现在给定一个数组:[6,3,2,7,1,3,5,4],我们需要使用归并算法对其排序,其大致过程如下图所示:

阶段可以理解为就是递归拆分子序列的过程,递归的深度为log2n。而治的阶段则是将两个子序列进行排序的过程,我们通过图解看看治阶段最后一步中是如何将[2,3,6,7]和[1,3,4,5]这两个数组合并的。

图中左边是复制的临时数组,而右边是原数组,我们将左右指针对应的值进行大小比较,将较小的那个数放入原数组中,然后将相应的指针右移。比如第一步中,我们比较左边指针L指向的2和右指针R指向的1,R指向的1小,则把1放入原数组中的第一个位置中,然后R指针向右移动。后面再继续,直到左边临时数组的元素都按序覆盖了右边的原数组。最后我们通过上图再结合源码来看看吧:

class Solution {public int[] sortArray(int[] nums) {sort(0, nums.length - 1, nums);return nums;}// 分:递归二分private void sort(int l, int r, int[] nums) {if (l >= r) return;int mid = (l + r) / 2;sort(l, mid, nums);sort(mid + 1, r, nums);merge(l, mid, r, nums);}// 治:将nums[l...mid]和nums[mid+1...r]两部分进行归并private void merge(int l, int mid, int r, int[] nums) {int[] aux = Arrays.copyOfRange(nums, l, r + 1);int lp =l, rp = mid + 1;for (int i = lp; i <= r; i ++) {if (lp > mid) {                // 如果左半部分元素已经全部处理完毕nums[i] = aux[rp - l];rp ++;}  else if (rp > r) {          // 如果右半部分元素已经全部处理完毕nums[i] = aux[lp - l];lp ++;} else if (aux[lp-l] > aux[rp - l]) { // 左半部分所指元素 > 右半部分所指元素nums[i] = aux[rp - l];rp ++;} else {                        // 左半部分所指元素 <= 右半部分所指元素nums[i] = aux[lp - l];lp ++;}}}
}
复制代码

我们可以看到,分阶段的时间复杂度是logN,而合并阶段的时间复杂度是N,所以归并算法的时间复杂度是O(N*logN),因为每次合并都需要对应范围内的数组,所以其空间复杂度是O(N);

归并排序(迭代版)

上面的归并排序是通过递归二分的方法进行数组切分的,其实我们也可以通过迭代的方法来完成分这步,看下图:

其因为数组,所以我们直接通过迭代从1开始合并,其中sz就是合并的长度,这种方法也可以称为自底向上的归并,其具体的代码如下

class Solution {public int[] sortArray(int[] nums) {int n = nums.length;// sz= 1,2,4,8 ... 排序for (int sz = 1; sz < n; sz *= 2) {// 对 arr[i...i+sz-1] 和 arr[i+sz...i+2*sz-1] 进行归并for (int i = 0; i < n - sz; i += 2*sz ) {merge(i, i + sz - 1, Math.min(i+sz+sz-1, n-1), nums);}}return nums;}// 和递归版一样private void merge(int l, int mid, int r, int[] nums) {int[] aux = Arrays.copyOfRange(nums, l, r + 1);int lp =l, rp = mid + 1;for (int i = lp; i <= r; i ++) {if (lp > mid) {nums[i] = aux[rp - l];rp ++;}  else if (rp > r) {nums[i] = aux[lp - l];lp ++;} else if (aux[lp-l] > aux[rp - l]) {nums[i] = aux[rp - l];rp ++;} else {nums[i] = aux[lp - l];lp ++;}}}
}
复制代码

总结

归并排序是一种十分高效的排序算法,其时间复杂度为O(N*logN)。归并排序的最好,最坏的平均时间复杂度均为O(nlogn),排序后相等的元素的顺序不会改变,所以也是一种稳定的排序算法。归并排序被应用在许多地方,其java中Arrays.sort()采用了一种名为TimSort的排序算法,其就是归并排序的优化版本。

http://www.yayakq.cn/news/502908/

相关文章:

  • 专用车网站建设哪家专业电子商务平台建设预算
  • 邯郸网站制作设计做网站一般建多大的页面
  • .net 微信网站开发手机网站会员中心模板
  • 怎么查找网站备案主体游戏推广代理app
  • 湛江企业模板建站做网站用微软雅黑字体被告侵权
  • 怎么给自己网站做搜索框wordpress找不到页面内容编辑
  • 住房和城乡建设部网站诚信评价网页制作及网站建设
  • 免费做四年级题的网站遂昌网站建设
  • 宁波市有哪些网站建设公司网站开发设计电子书
  • 摄影作品网站知乎网站建设运营要求
  • 邢台做网站价位学院网站建设自评
  • 网站吸引客户给一个网站如何做推广
  • 广东网站建设制作价格低东莞市城乡建设网
  • 长沙百度搜索网站排名昆明企业网站建设
  • 杭州滨江网站制作wordpress分享qq插件下载地址
  • 网站建设网络推广代理公司程序员常用的工具有哪些
  • 网站被降权如何恢复昆山室内设计学校
  • 微信网站建设费用计入什么科目中国企业排名前十
  • php做网站的技术难点目前主流的跨境电商平台有哪些
  • 德阳网站建设求职简历汉阳网站推广公司
  • 个人网站可以放广告吗深圳工业设计中心
  • 沈阳网站建设哪里好找不到自己做的dw网站
  • 网络广告网站外贸英语 网站
  • 做谷歌网站使用什么统计代码免费软件制作网站
  • 网站建设销售要懂什么市体育局网站 两学一做
  • 怎么买做淘宝优惠券网站网站域名选择的原则
  • 辽宁省建设工程信息网官网新网站入口无为做网站
  • 那个啥的网站推荐下岳溥庥网站建设
  • 网站怎么制作浙江城乡建设信息港
  • 网站次页汽车网站策划