算法笔记 ( 一 )

什么是时间复杂度:

一个算法流程中,常数操作数量的指标

什么常数时间操作:  

     大O描述的是算法的运行时间和输入数据的关系

    一个操作 如果和数据量没有关系,每次都是固定时间内操作,叫做常数操作。如做加减操作,数组寻址
    
    O(1)一次常数操作的平均时间
    
    例如:for循环取出一个数及数组遍历数组寻址都为常数操作
    
    O(logn)与忽略对数的底(log10n)或者是(  log2n)
    for(int i=1;i<n;i+=i){}
    
    优化可以考虑通过推导的额数学公式将时间复杂度降一个维度(例如:等差数列求和)
        

什么是正确的算法:

对问题的独到见解;优化;代码规范;容错性


开始答题注意:

1.关注题目中的条件:

例如:

给定一个有序数组                -->      二分查找法
设计一个O(nlogn)的算法      -->      logn 的算法基本与分治法(搜索树)相关 有可能与排序相关 
无需考虑额外的空间             -->      开辟额外的空间 再空间换时间
数据规模大概是10000          -->      采用 O(n2)

注:当没有思路的时候不要忽略暴力解法。暴力解法通常是思考的起点。 

2.如何优化算法:

* 遍历常见的算法思路
* 遍历常见的数据结构
* 空间和时间的交换(哈希表)
* 预处理信息(排序)
* 在瓶颈处寻找答案:O(nlogn)+O(n^2);O(n^3)

3.实际编写问题:

* 极端条件的判断      -->      数组是否为空?字符串为空?数量为0?指针为NULL?
* 变量名
* 模块化,复用性
 归并排序算法时间复杂度默认为O(nlog)

4.空间复杂度

* 多开一个为n的辅助数组:O(n)
* 多开一个辅助的二维数组:O(n^2)
* 多开常数空间(如临时变量):O(1)
注:递归调用是有空间代价的递归深度有多少 空间复杂度就有多少

5.小技巧及学习思路

* 异或运算符特点:一个数据A对一个数据B异或两次的结果是数据A常用来数据交换

* 计算时间复杂度注意循环判断条件以及每次遍历条件

* 学习优秀的程序思想 并尝试分享一些自己的学习心得与完成和在做的项目


排序 :

注意:mid=(l+r)/2 当l和r为很大的数字时会发生溢出的错误

    交换排序 ( 冒泡排序 O ( n^2 ) )

    快速排序O(nlogn)) 快速排序可求第n大数判断在第一个比较数左边还是右边可进行舍弃另一边


    插入排序 ( 直接插入排序 O( n^2),希尔排序n^(2/3) ) 


    选择排序 ( 简单选择排序 O ( n^2 ),堆排序)
    
    归并排序 ( 自顶向下归并排序,自底向上归并排序 (没有通过索引直接获取元素适合于链表排序)) O(nlogn)  
    Todo --> 链表采用自底向上归并排序
    最后一次归并可求逆数对当后一半在为排序完前一组数组进行赋值

    堆排序思路:

    最经典可通过数组存储从下标1开始  
    二叉树从上到下从左到右逐次+1  
    数组的索引对应二叉树的索引

    最大堆:(最小堆类似)
    堆中的某个节点的值总是不大于其父节点的值(可能大于其兄弟节点);
    堆总是一个完全二叉树。(所有子节点优先集中在二叉树的左边)
    
    每一个节点左节点是其两倍 右节点是其两倍加1  
    寻找父节点可以通过计算机的方式i/2 向下取整
    
   原地堆化: heapify 可以优化从一个空堆逐渐插入n个元素 O( nlogn ) -- > O(n)

    
    基数排序


动态规划和贪心算法:

分治递归:通常将问题一分为二再进行操作,而递归往往会出现重复判断 分治则进行更优化   

贪心算法(Greedy):在对问题求解时,总是做出当前看来是最好的选择(具有一定的局限性)-->互相为倍数的情况比较适用

适用场景:

    问题可以分解为子问题来解决。子问题的最优解能递推到最终问题的  
    最优解。子问题的最优解为最有子结构
    
贪心算法与动态规划不同:

    在于它堆子问题的解决方案都能做出选择,不能回退
    动态规划(DP)会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值