算法复杂度和合并果子题解
技术微刊
算法
要了解算法,就要先了解算法的时间复杂的。
该如何判断一个算法的好坏,很关键的一点就是拥有较少的程序运行时间,也就是较小的时间复杂度(time complexity)。那么什么是算法的复杂度呢:
简而言之,就是一个算法要花多少时间执行。
我们先以一个简单的算法导入概念:
#include<stdio.h>
int main(){
int a[10]={32,44,1,65,123,48,6,133,34,78};int i,max; max=a[0]; for(i=0;i<10;i++){if(a[i]>max)max=a[i];}printf("%d\n",max);return 0;
}
中间那部分是寻找最大值的算法。
指令 | 执行次数 |
---|---|
max=a[0] | 1 |
for(i=0;i<10;i++) | 9 (n-1) |
if(a[i]>max)max=a[i] | 9 (n-1) |
printf("%d\n",max) | 1 |
算法复杂度 | 20 (2n) |
这个算法的复杂度是2n, n是输入数值的个数。
我们常常使用O(n) (读作big O n)来表示一个算法的时间复杂度。 一般来说O里面是多次的式子,我们取最高次。
如一个算法复杂度是 n4+n2+n
那我们取写作O(n4)
排序介绍
下面我介绍二种排序:桶排序,插入排序
桶排序:
个人认为桶排序是最适合初学者,而且桶排序在一般情况下是最快的排序。
比如我们要排序的数字是8 5 5 3 2
那么我们可以申请一个一维数组a[10]来存放
首先我们将数组中的元素全部置0处理
下面开始处理要排序的数
首先是8 那么将a[8]++变成a[8] =1
然后是5 那么将a[5]++变成a[5]=1
后面一个元素还是5那么还是将a[5]++变成a[5]=2
以此类推
最后我们从1开始到数组结束
如果数组的元素大于0就输出这个数
实现代码
#include<stdio.h>
int main(){int i;int a[10]={0};int b[5]={8,5,5,3,2};for(i=0;i<5;i++){a[b[i]]++;}for(i=0;i<11;i++){while(a[i]>0){printf("%d ",i);a[i]--;}}return 0;
}
你们可以把标记数组想象为桶,要排序的数字就是在对应的桶里放小旗子。然后从第一个桶开始输出有旗帜的桶。
所以可以得知桶排序算法复杂度就是桶的个数N和要排序的数据个数M之和就是O(N+M)
对比冒泡排序的 O(N2) 是不是快多了呢。但是桶排序有诸多的限制比如不能排序实数组,面对未知数组的大小的排序不是很好用。面对巨量的排序可能无法进行。
插入排序:
插入排序的核心思想就是插入,而且是插入有序的数组。你可以把要排序的数据的第一个元素想象成已经排过序的数,从第二个数开始插入到有序数列中。下面首先给出代码实现。我们从代码中先理解一下。插入的数首先和前面一个数比较,如果小于前面一个数那么前面一个数向后一位然后和再一个前面的数进行比较。如果比较失败那么插入这个数。
实现代码
#include<stdio.h>int main(){int a[10]={99 ,223,435,12,546,13,456 ,4523,124,438};int i,j,key;for(j=1;j<10;j++){key=a[j];i=j-1;while(i>=0&&a [i]>key){ //如果比它小则后移a[i+1]=a[i];i=i-1;}a[i+1]=key; }for(i=0;i<10;i++)printf("%d ",a[i]);return 0;}
插入排序的算法复杂度涉及到多重考虑这边直接给出答案 O(n2) 可以看出插入排序和冒泡拥有近乎一样的算法复杂度,但为什么还要使用插入排序呢?
插入排序在某些情况下可以说是优化算法的一个好方法:比如拓展训练合并果子一题:
这题看似简单实则暗藏小陷阱,看似只要把最小的依次加起来,但其实最小的加起来的数不一定还是最小,加一次过后的数组需要重新排序,但我们知道其实只有一个元素未排序,这时候插入排序便起到了作用。偷偷告诉你们小编也被坑过好几回用了选择排序最后TLE,所以我就选择了插入排序来优化我的算法。
实现代码
#include<stdio.h>
void pai(int a[],int n)
{int i,j,key; key=a[n]; //直接进行插入i=n-1;while(i>=1&&a[i]<key){a[i+1]=a[i];i=i-1;}a[i+1]=key;
}int main(){int sum,n,i,j,key,t,a[10001]; scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&a[i]);sum=0;for(j=1;j<=n;j++){key=a[j]; //第一次完整插入排序i=j-1;while(i>=1&&a[i]<key){a[i+1]=a[i];i=i-1;}a[i+1]=key; }while(n>1){t=a[n]+a[n-1];sum+=t;a[n-1]=t;n--; pai(a,n);}printf("%d\n",sum); return 0;
}
首先我把第一次输进去的数组进行从大到小进行排序,这是为了什么呢,因为它要求每次把最小的两个合并,如果从小到大,那么数组的前面会有空余,进行下一次操作时不会特别的方便,所以我就从大到小排序每回操作数组最后的两个数。然后我将最后两个数的和给道倒数第二个数同时另数组长度减一,这时候它就变成了这个数组最后一个元素,而前面的元素是有序的,只要把最后一个数插入进去即可。因为最小的两个数加起来也不会很大,实际只要比较较少次数函数变回返回结束。如9 4 3 2 最后两个相加给到倒数第二个元素,这时候数组变成9 4 5,我只需要比较一次即可插入算法复杂度及其小,如果我在这边用了选择或者冒泡,那么他就要进行 n2 次操作,n为数组的长度。极大优化了算法的效率。
算法复杂度和合并果子题解相关推荐
- 贪心算法——洛谷(P1090)[NOIP2004]合并果子
该题目也属于经典的贪心算法,在这里熟悉C++里优先队列的使用. 需要导入头文件: #include<queue> 从这个问题可以深挖出神奇的哈夫曼树问题. 因为这题里合并的是二叉树,所 ...
- PAT甲级1125 Chain the Ropes:[C++题解]贪心、优先队列、合并果子
文章目录 题目分析 题目来源 题目分析 来源:acwing 板子题:合并果子合并果子优先队列 分析:贪心策略是: 每次取最短的两条绳子a和b.该两条绳子合并为1条绳子,且长度变为a+b2\frac{a ...
- 合并果子_tyvj1066_vijos1097_codevs1063_贪心+堆
描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可以看 ...
- 洛谷——P1090 合并果子
题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...
- 排序代码(python,c++) 及 基本算法复杂度
0.导语 本节为手撕代码系列之第一弹,主要来手撕排序算法,主要包括以下几大排序算法: 直接插入排序 冒泡排序 选择排序 快速排序 希尔排序 堆排序 归并排序 1.直接插入排序 [算法思想] 每一步将一 ...
- 八大排序:Java实现八大排序及算法复杂度分析
目录 QUESTION:八大排序:Java实现八大排序及算法复杂度分析 ANSWER: 一:冒泡排序 1.算法分析 2.时间复杂度分析 3.代码 二:选择排序 1.算法分析 2.时间复杂度分析 3.代 ...
- 【codevs1063NOIP04PJ】合并果子,贪心の钻石
1063 合并果子 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 在一个果园里,多多已经将所有的果子打了下来,而且按果 ...
- Vijos P1097 合并果子【哈夫曼树+优先队列】
描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可以看 ...
- JZOJ 1775. 合并果子2 (Standard IO)
1775. 合并果子2 (Standard IO) Time Limits: 1000 ms Memory Limits: 65536 KB Description 在一个果园里,多多已经将所有的果子 ...
- java合并果子_C++(STL)树-堆结构练习——合并果子之哈夫曼树
priority_queue 对于基本类型的使用方法相对简单. 他的模板声明带有三个参数,priority_queue Type 为数据类型, Container 为保存数据的容器,Functiona ...
最新文章
- 不再重复造轮子,AI 给你推荐更好的代码,还没bug
- 时间序列挖掘-DTW加速算法FastDTW简介
- 二叉查找树 Java实现
- python 读取yml文件_Python 读取 yaml 配置文件 | 文艺数学君
- SLAM: Inverse Depth Parametrization for Monocular SALM
- Elasticsearch使用REST API实现全文检索
- mongodb @aggregation 返回字段映射不上_Spring Boot 操作 MongoDB
- 腾讯云服务器CentOS 7安装JAVA JDK并运行class文件
- 超越Hadoop的大数据分析之图形处理尺寸
- HashTable HashMap区分
- 阶段1 语言基础+高级_1-3-Java语言高级_07-网络编程_第1节 网络通信概述_5_端口号...
- 正则表达式,js表单验证
- 医院绩效考核管理平台建设方案
- 电脑复制,电脑复制粘贴,详细教您电脑不能复制粘贴怎么办
- 读计算机网络得学五笔吗,新手学五笔打字的步骤
- UIView隐藏超出superview的部分
- Same Parity Summands
- ANX6585D VSP/VSN 正负压输出,适用于TFT-LCD小屏应用,兼容FP7721、NT50198。
- 一站式原创文章神器,让你轻松创作高质量文章
- 十二.vue-resourse实现get,post,jsonp请求
热门文章
- python爬虫总结,看这篇就够了
- PIXI入门-PIXI文档翻译(1)
- Taro项目中设置了设计稿尺寸
- 前端Jquery使用pagination.js插件进行分页
- excel单元格内容拆分_Excel | 单元格内容换行的两种方法
- 复杂 Excel 表格导入导出的最简方法
- 基于STM32:情侣互动玩偶(设计方案+源码+3D图纸+AD电路)
- JavaWeb宿舍管理系统环境搭建运行教程
- mysql 锁住一行数据_MySQL-锁
- 搜狗首席科学家柳超博士谈“字根嵌入”让机器更懂中文