算法基础思想

本文介绍了算法的基础思想,包括算法的特性、好算法的标准以及时间、空间复杂度分析。重点讨论了数据结构的时间复杂度,例如图的BFS和DFS搜索,以及字符串子串的查找。此外,还提出了提高代码质量的技巧,并列举了LeetCode中涉及的二叉树和N叉树遍历问题,以及递归的使用。
摘要由CSDN通过智能技术生成

Go 语言—数据结构和算法项目推荐
95% 的算法都是基于这 6 种算法思想
在这里插入图片描述

0. 算法

王道考研 数据结构

1.算法的特性

  1. 有穷性 2. 确定性 3.可行性 4. 输入 5. 输出

2. 好算法

  1. 正确性 2.可读性 3.健壮性(非法输入处理) 4.高效率和低存储量需求

在这里插入图片描述
在这里插入图片描述

3. 算法的时间复杂度

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 空间复杂度

在这里插入图片描述

1. 数据结构的时间复杂度

  • 图的时间复杂度O(n)
    一种是邻接表存储,一种是邻接矩阵存储。对于BFS,使用邻接表每个顶点都要遍历一次所以时间复杂度是O(V)(V表示点的个数),在搜索了邻接的顶点时每条边又至少遍历一次,所以总的时间复杂度应该是O(V+E)(E表示边的个数)。对于邻接矩阵,不存储边的信息,每个顶点遍历一次是要走完矩阵的,所以时间复杂度是O(VV).对于不管是使用邻接矩阵存储还是邻接表存储,都要使用一个辅助的队列,所以邻接点都入队一次的空间复杂度是O(V)。
    对于DFS,不需要用队列,可以使用递归,递归就需要一个递归的工作栈,所以空间复杂度是O(V),同样的DFS也有邻接表存储和邻接矩阵存储,使用邻接矩阵仍是所有的结点都要遍历一次,所以时间复杂度是O(V
    V),使用存储表存储,访问所有顶点的时间复杂度是O(V),访问邻接点时间复杂度是O(E),所以总的时间复杂度是O(V+E)。这是遍历算法,如果是搜索算法就是取最坏的情况所有节点访问一次也就是O(V)

  • 图搜索算法(DFS(深度优先),BFS(广度优先))😮(n)
    在这里插入图片描述

2. string

字符串的子串必须是连续的,如"abcd"的子串有"ab","bcd"等,但是"ac"不是"abcd"的子串。因此,对于长度为n的字符串,共有1+2+…+n个非空子串,即(n+1)*n/2个,是O(n^2)级别的
字符串的子序列不需要是连续的,因此对于长度为n的字符串的子序列,每个字符都有选或不选两种可能。 因此其子序列的数量是指数级别O(2^n)的

3. 不好的代码风格

  • 异常检测:需要对空对象进行特判;
  • 变量命名:尽量不要用单个字符进行命名;
  • 代码美观:在必要的位置需要加上空格;
  • 缩进过多:通过用函数包装代码块减少代码的缩进。(尽量不超过3层)

4.快速提高 Coding Quality 的十二个技巧

  1. Coding Style 相关:
    • 二元运算符两边加空格,单元运算符不加空格
    • 花括号和 for, if 之间要加空格(Java),圆括号和 if 之间要加空格
    • 用空行分隔开不同的逻辑块
    • 逗号后面加空格
  2. Readability 相关
    • 函数名和变量名用1-2个单词作为名称
    • 确保一个函数内部不超过 3 层缩进(indention)(缩进通常使用4个空格)
    • 多用子函数来减少入口函数的代码量
    • 多用 continue 少用 if
  3. Bug Free 相关
    • 不管有没有可能出问题,都要对入口函数的参数进行异常检测
    • 访问一个下标的时候,一定要确保这个下标不会越界
    • 访问一个对象的属性或者方法时,一定要确保这个对象不是空
    • 不用全局变量

5. 查找字符串子串第一次出现的索引

Rabin-Karp算法(时间复杂度O(n+m))
在这里插入图片描述

在这里插入图片描述

6. 时间复杂度

优化:升维,空间换时间
在这里插入图片描述
在这里插入图片描述
二叉树遍历 O(n)
排好序的二维矩阵O(n)
归并排序 O(n log n)
归并排序和快速排序

7.空间复杂度

和时间复杂度类似,但是更加简单。

主要有两条原则:

数组的长度

如果代码里开了数组:

数组的长度,基本上就是空间复杂度。

一维数组:O(n)

二维数组:O(n^2)

递归的深度(特殊说明)

如果有递归:

递归最深的深度,就是空间复杂度的最大值。

O(n)

数组 + 递归

两者之间的最大值,就是空间复杂度

8. 跳表

在这里插入图片描述
优点:原理简单、实现简单,方便扩展,效率更高
缺点:维护成本高,插入、删除时间复杂度O(logn),插入和删除会导致索引不工整
使用案例:Redis.zset、LevelDB
随机查询时间复杂度O(logn)
空间复杂度O(n)

9. leetcode

  1. 二叉树的中序遍历
    https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

  2. 二叉树的前序遍历
    https://leetcode-cn.com/problems/binary-tree-preorder-traversal/

  3. 二叉树的后序遍历
    https://leetcode-cn.com/problems/binary-tree-postorder-traversal/

  4. N叉树的前序遍历
    https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal/

  5. N叉树的层序遍历
    https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/

  6. 爬楼梯
    https://leetcode-cn.com/problems/climbing-stairs/

  7. 括号生成
    https://leetcode-cn.com/problems/generate-parentheses/

  8. 翻转二叉树
    https://leetcode-cn.com/problems/invert-binary-tree/

  9. 验证二叉搜索树
    https://leetcode-cn.com/problems/validate-binary-search-tree/

  10. 二叉树的最大深度
    https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

  11. 二叉树的最小深度
    https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/

  12. 二叉树的序列化与反序列化
    https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/

  13. 二叉树的最近公共祖先
    https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

  14. 从前序与中序遍历序列构造二叉树
    https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

  15. 组合
    https://leetcode-cn.com/problems/combinations/

  16. 全排列
    https://leetcode-cn.com/problems/permutations/

  17. 全排列 II
    https://leetcode-cn.com/problems/permutations-ii/

10.递归

python

def recursion(level, param1, param2, ...):
# recursion terminator 递归终止条件 
if level > MAX_LEVEL:
process_result
return

# process logic in current level 当前层的代码处理逻辑
process(level, data...)

# drill down 进入到下一层递归中去
self.recursion(level+1, p1, ...)

# reverse the current level status if needed 状态回复

Java

    public void recur(int level,int param){
        //terminator
        if(level>MAX_LEVEL){
            //process result
            return;
        }
        //process current logic
        process(level,param);
        
        //drill down
        recur(level:level+1,newParam)
        
        //restore current status
        }

js

 const recursion = (level, params) =>{
   // recursion terminator 
 if(level > MAX_LEVEL){  
      process_result  
         return    }  
       // process current level   process(level, params)  
        //drill down   
        recursion(level+1, params)  
         //clean current level status if needed   }      
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值