leetcode刷题经验

leetcode刷题经验

注意

1.按算法的分类来选题和刷题,比如一个时间段,只刷链表题,待刷得差不多的时候,接下来再刷二叉树的题
2.解题三部曲
看懂题目、分析,推导解法、将思路转换为代码
3.推荐三本有益于面试的书籍,分别是:《剑指 offer》《编程珠玑》《编程之美》
4.算法,主要是以下几种:

基础技巧:分治、二分、贪心
排序算法:快速排序、归并排序、计数排序
搜索算法:回溯、递归、深度优先遍历,广度优先遍历,二叉搜索树等
图论:最短路径、最小生成树
动态规划:背包问题、最长子序列
数据结构,主要有如下几种:

数组与链表:单 / 双向链表
栈与队列
哈希表
堆:最大堆 / 最小堆
树与图:最近公共祖先、并查集
字符串:前缀树(字典树) / 后缀树
5.如果你时间比较紧迫,为了找工作而刷题,我建议你先刷热门推荐,一共两百多道题

时间复杂度和空间复杂度

数组 哈希

1.哈希表可以用来通过空间换时间,提高了空间复杂度降低时间复杂度
2.两个有序数组合并-归并排序
求两数组中位数
堆排序

链表

1.链表的逆序加法,通过递归遍历,按节点逐个计算
2.链表的排序 分治

字符串

1.滑动窗口(配合hashset)解决单链表求子串的问题

动态规划

动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路
给定k阶段状态变量x(k)的值后,如果这一阶段的决策变量一经确定,第k+1阶段的状态变量x(k+1)也就完全确定,即x(k+1)的值随x(k)和第k阶段的决策u(k)的值变化而变化,那么可以把这一关系看成(x(k),u(k))与x(k+1)确定的对应关系,用x(k+1)=Tk(x(k),u(k))表示。这是从k阶段到k+1阶段的状态转移规律,称为状态转移方程、
最优化原理:作为整个过程的最优策略,它满足:相对前面决策所形成的状态而言,余下的子策略必然构成“最优子策略”。最优性原理实际上是要求问题的最优策略的子策略也是最优
动态规划算法的关键在于解决冗余,这是动态规划算法的根本目的。动态规划实质上是一种以空间换时间的技术,它在实现的过程中,不得不存储产生过程中的各种状态,所以它的空间复杂度要大于其他的算法。选择动态规划算法是因为动态规划算法在空间上可以承受,而搜索算法在时间上却无法承受,所以我们舍空间而取时间

能用动态规划解决的问题

大规模问题的答案可以由小规模问题的答案递推得到,也就是​[公式]的值可以由​[公式]中的个别求得
f(n) ​可以基于 f(n-1)​求得

应用动态规划——将动态规划拆分成三个子目标

1.建立状态转移方程
这一步没太多的规律可说,只需抓住一个思维:当做已经知道​f(1)~f(n-1)的值,然后想办法利用它们求得f(n)。
2.缓存并复用以往结果
3.按顺序从小往大算
这里的“小”和“大”对应的是问题的规模,在这里也就是我们要从f(0)、f(1)、…、f(n)依次顺序计算。

动态规划是要我们在推导出状态转移方程后,根据状态转移方程用计算机暴力求解出来
就是因为要暴力计算,所以前面说的目标有两个是涉及到代码层面上:

  • 缓存中间结果:也就是搞个数组之类的变量记录中间结果
  • 按顺序从小往大算:也就是搞个for循环依次计算

知乎详解动态规划

动态规划 -自上而下递归
-自下而上

适用题目

最短路径、数列、方格不同路径

分治法

滑动窗口

滑动窗口的思想:
用i,j表示滑动窗口的左边界和右边界,通过改变i,j来扩展和收缩滑动窗口,可以想象成一个窗口在字符串上游走,当这个窗口包含的元素满足条件,即包含字符串T的所有元素,记录下这个滑动窗口的长度j-i+1,这些长度中的最小值就是要求的结果

二叉树

求路径和 :递归、分析每个最小子树
迭代和递归的思想和思考方式
哈希的使用

DFS 深度优先遍历
广度优先遍历
层序遍历

二维矩阵

二维数组
贪心算法

单调(递减)栈


单链表
关键字

双指针、虚拟头节点

你可能感兴趣的:(算法,算法)