【算法day1】复杂度和简单排序算法(1)
复杂度和简单排序算法
时间复杂度
以一个排序(选择排序)操作举例

假设我有一个数组,我要找出其中的最小值放到0的位置上
那么
第一次我会遍历数组中N个数(在0位置处),找出最小的数交换到0位置【看了(寻址)N次,比较N次,一次交换】
第二次我会看遍历数组中N-1个数(在1位置处),找出最小的数交换到1位置【看了(寻址)N-1次,比较N-1次,一次交换】
第三次我会看遍历数组中N-2个数(在2位置处),找出最小的数交换到2位置【看了(寻址)N-2次,比较N-2次,一次交换】
以此类推,遍历的范围会缩小,数也按从小到大排好
总结一下:
一共看了N+(N-1)+(N-2)+(N-3)+...次(等差数列)
一共比了N+(N-1)+(N-2)+(N-3)+...次(等差数列)
一共换了N次
上述对常数的操作次数加起来可以写成:aN2+bN+C
那么时间复杂度就是在常数操作数量级的表达式(上式)中,最高次项的次数,例如上面这个排序的时间复杂度就是O(N2)
异或
结论:
1、0异或N对于N
2、N异或N对于0
3、满足交换、结合律
4、一批数要异或在一起,那么不论先后顺序,得到的结果是一样的
快速交换a、b的值
int a = 甲;int b = 乙;
那么只需
a = a⊕b;(a = 甲⊕乙,b = 乙)
b = a⊕b;(a = 甲⊕乙,b = 甲⊕乙⊕乙 = 甲)
a = a⊕b;(a = 甲⊕乙⊕甲 = 乙,b = 甲)
便可完成a、b交换(不用额外申请空间,前提是a、b指向两个不同的内存空间)
找奇偶数
问题描述:
在一个数组中
1、只有一个数出现奇数次,其余的出现偶次,把它找出来
2、有两个数出现奇数次,其余的出现偶次,把它找出来并且给出这两个数是什么
要求时间复杂度为O(N),空间复杂度为O(1)
思路:
1、第一种情况
准备一个数int eor = 0
用eor把数组从头异或到尾
假如数组是[a,b,c,...]
那么
eor = eor⊕a;
eor = eor⊕b;
eor = eor⊕c;
...
最后eor 就是出现次数为奇数的那个数
例如数组为[2,1,3,1,3,1,3,2,1]
用eor去异或,最后结果一定是3
因为上述数组在以后时无需考虑顺序,数组可看成
[1,1,1,1,2,2,3,3,3]
4个1异或完是0;
2个2异或完是0;
3个3异或完是它本身(3);
结束
2、第二种情况
设这两个出现奇数次的数是a和b,并且我们知道两者不等
准备一个数int eor = 0
用eor把数组从头异或到尾,那么最后eor = a⊕b
先跟所有的偶数次的异或得到0,然后跟奇数次的a异或得a,再跟奇数次的b异或剩个b,最后成了a⊕b
因为a不等于b,所以eor不等于0,所以eor一定在某一位上不等于0(为1)
假设eor是在第8位上不为0,那么a和b的第8位一定是不一样的
再准备一个变量eor2
只有当数组中某个数的第8位是0(或者1),才把这个数同eor2异或,那么最后eor2会等于a或b的其中一个
之后再用eor异或eor2就可以得到另一个数
tips:
怎么着某一位是指定数的数?(比如第8位是1)
这个问题可以归结成:提取出最右侧的1
假设
k:1010111100
k取反:010100011
k取反+1:010100100
k&k取反+1 = 000000100,提取得到最右侧的1
在位运算中,需要把一个数最右侧的1提取出来
只需将这个数和它自身取反后加1的结果做与运算即可
结束
【算法day1】复杂度和简单排序算法(1)的更多相关文章
- 简单排序算法 C++类实现
简单排序算法: 冒泡排序 插入排序 选择排序 .h代码: // // SortClass.h // sort and selection // // Created by wasdns on 16/1 ...
- 简单排序算法设计(Java)
总共有八种排序算法,还是慢慢看吧 1.简单排序算法 简单排序算法就是设置标兵,逐个比较数,然后查找插入位置,插入 public static void p(int[] a){ for(int i=0; ...
- 《算法4》2.1 - 选择排序算法(Selection Sort), Python实现
选择排序算法(Selection Sort)是排序算法的一种初级算法.虽然比较简单,但是基础,理解了有助于后面学习更高深算法,勿以勿小而不为. 排序算法的语言描述: 给定一组物体,根据他们的某种可量化 ...
- Java数据结构和算法(三):常用排序算法与经典题型
常用的八种排序算法 1.直接插入排序 我们经常会到这样一类排序问题:把新的数据插入到已经排好的数据列中.将第一个数和第二个数排序,然后构成一个有序序列将第三个数插入进去,构成一个新的有序序列.对第四个 ...
- JavaScript 数据结构与算法之美 - 十大经典排序算法汇总(图文并茂)
1. 前言 算法为王. 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手:只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 ...
- python实现简单排序算法
算法 递归两个特点: 调用自身 有穷调用 计算规模越来越小,直至最后结束 用装饰器修饰一个递归函数时会出现问题,这个问题产生的原因是递归的函数也不停的使用装饰器.解决方法是,只让装饰器调用一次即可,那 ...
- 用javascript实现简单排序算法
声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 本文为楼主自己的学习记录文章,若有不当之处请斧正. 本文主要记录排序算法 [冒泡排序] 感觉这个是最简单的排序算法了.直接引用维基百科里的 ...
- js的几种简单排序算法及其效率实测
function swap(arr,index1,index2){ var t = arr[index1]; arr[index1] = arr[index2]; arr[index2] = t; } ...
- 三种简单排序算法(java实现)
一.冒泡排序 算法思想:遍历待排序的数组,每次遍历比较相邻的两个元素,如果他们的排列顺序错误就交换他们的位置,经过一趟排序后,最大的元素会浮置数组的末端.重复操 作 ...
- [读书笔记]算法(Sedgewick著)·第二章.初级排序算法
本章开始学习排序算法 1.初级排序算法 先从选择排序和插入排序这两个简单的算法开始学习排序算法.选择排序就是依次找到当前数组中最小的元素,将其和第一个元素交换位置,直到整个数组有序. public s ...
随机推荐
- [转帖]优化超大 Nginx 配置导致的内存碎片
https://blog.openresty.com.cn/cn/ngx-cycle-pool-frag/?src=org_news 章亦春发布于 Feb 14, 2023更新于 Mar 2, 202 ...
- [转帖]docker编译speccpu2017
实验步骤: 1.下载docker和speccpu2017 2.docker下载镜像,创建容器 3.将下载的宿主机speccpu2017拷贝到docker创建的容器中(docker cp) 4.在doc ...
- [转帖]/etc/profile 和 /etc/profile.d/ 的区别
https://my.oschina.net/calmsnow/blog/2989570 /etc/profile 是文件, /etc/profile.d/ 是目录,用在设置环境变量方面,/etc ...
- [转帖]【k8s】1、基础概念和架构及组件
文章目录 一.kubernetes概述 1.什么是kubernetes? 2.应用程序部署方式的演变 3.为什么要用kubernetes? 二.kubernetes 特性 三.Kubernetes集群 ...
- Vue2 里如何优雅的清除一个定时器
绝大多数人清除定时器的方法 <script> export default { data() { return { timer: null } }, mounted() { this.ti ...
- 去除 i 标签的倾斜样式;如何引入本地的阿里字体图标
去除 i 标签的倾斜样式 i{ font-style:normal; } 如何引入本地的阿里字体图标 将代码下载下来 当然你将下载下载来的资源有用的放在静态资源中 然后在 main.js 引入: ma ...
- c++基础之函数
距离上次更新又过了一周,又该更新新的读书笔记了.本次更新的主要是c++中函数部分的内容 c++ 中的函数与c语言中的函数大致用法或者语法是一样的,这里就不就这点详细展开了.需要注意的是c/c++中并没 ...
- 微信小程序-behaviors
什么是 behaviors behaviors 是用于组件间代码共享的特性,类似于一些编程语言中的 "mixins" 每个 behavior 可以包含一组属性,数据,生命周期函数和 ...
- 2.1 Windows驱动开发:内核链表与结构体
在Windows内核中,为了实现高效的数据结构操作,通常会使用链表和结构体相结合的方式进行数据存储和操作.内核提供了一个专门用于链表操作的数据结构LIST_ENTRY,可以用来描述一个链表中的每一个节 ...
- 本地Nuget包管理
nuget.org有时候会抽风,VS无法自动下载程序包.这时,我们可以配置本地nuget包搜索路径. 1 下载Nuget package 以anycad rapid sdk为例,可以先从百度云盘下载最 ...