目录
0 前置
1 内容回顾
学习组合拳
对复杂度的认识
数据结构:
数组:Array
链表:List
哈希表:
字符串:
栈与队列:
二叉树:
回溯:
贪心:
动态规划:Day38-Day57
单调栈:
2 总结与展望
刷题量:
一群朋友:
一点反思:
怼点鸡汤:
0 前置
背景:非科班,自学入坑(黄金坑)3个月,基本是0基础,类似:Java语法和接口方法调用不熟悉,第一次刷力扣发呆20min。
代码随想录一刷复盘230511_dannky_Z的博客-CSDN博客
在跟训练营之前,自己抄了一遍代码随想录网站上的题目内容,依靠自我鞭策。但基础太差,不见效果反而容易受挫不乏自我怀疑,果断花钱买服务、买环境、买时间。时间是生命的度量,所以买时间就是买生命啊!!!但,我还是想说,算法学习,没有捷径,靠的就是积累经验,多刷题,勤思考,做总结。这似乎符合所有内容的学习方式,好像发现了什么,但又没发现什么。
1 内容回顾
学习组合拳
先概览再深入。先解决问题,再求优化解(先追求暴力解题,有个理解基础也方便探究优化方式)。遇到不会的看题解、看视频,视频看迷糊的手动画图,把思路捋顺。比如:手动模拟递归,就大概知道代码是怎么走的(运行顺序和过程),对回溯的理解也会有帮助。
从这里得到一个道理,学习永远是诚于己。会了就是会了,不会就是不会。
对复杂度的认识
空间复杂度:体现在栈开销和堆开销。时间复杂度:体现在被遍历节点数或元素个数。
栈开销主要是方法的调用上,具体体现在方法的调用深度或着层数上,比如:在二叉树递归和回溯法递归,普通二叉树最差情况下是一个单向的链表,调用深度为元素个数n决定,此时(栈)空间复杂度为O(n),时间复杂度同样体现在遍历的节点个数n上,时间复杂度为O(n)。堆空间的开销主要体现在新数组或元素的复制上。对于二叉搜索树,时间复杂度和空间复杂度均为O(logn)(类似数组的二分查找,如果不知道的话,记住结论即可,不用证明)
数据结构:
数组:Array
自定义:内存空间中一串连续的存储空间,分配空间大小固定。
操作:循环暴力解法,在此基础上常用二分查找、双指针优化题解。
代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。_dannky_Z的博客-CSDN博客
代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结_dannky_Z的博客-CSDN博客
代码随想录算法训练营 | 数组小结_dannky_Z的博客-CSDN博客
链表:List
自定义:由节点组成,每个节点由数据和指向下一节点的指针,节点之间通过指针链接,在内存空间分布不一定连续。
类型:分为单向链表、双向链表、单向循环链表、双向循环链表。
操作:设置虚拟头节点,临时节点,改变指针指向,完成增删改。
代码随想录算法训练营第三天 | 203.移除链表元素 707.设计链表 206.反转链表_dannky_Z的博客-CSDN博客
代码随想录算法训练营第四天| 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点 (面试题) 02.07. 链表相交 142.环形链表II_dannky_Z的博客-CSDN博客
哈希表:
定义:Key-Value的形式存储数据,Key和Value的内容没有限制,两者通常为String/Integer类型的数据。
操作:map.containsKey()、map.getOrDefault(),相关方法还不够熟练...
补充:
HashMap:HashMap 使用了数组和链表(或红黑树)的组合实现。具体来说,它使用了数组作为底层的数据结构,每个数组元素是一个链表(或红黑树)的头节点。当发生哈希冲突时,即多个键值对被映射到同一个数组索引上时,它们会以链表(或红黑树)的形式存储在同一个数组索引位置上。
HashSet:HashSet 是基于 HashMap 实现的,它使用 HashMap 的键来存储元素,而值则为一个固定的常量对象。HashSet 实际上是一个不允许重复元素的集合,它通过 HashMap 来实现元素的存储和查找。
ArrayList:ArrayList 使用了动态数组作为底层的数据结构。它可以根据需要自动扩容,并且支持随机访问和快速的插入、删除操作。ArrayList 的实现是基于数组的,当需要插入或删除元素时,可能需要进行数组的拷贝和移动操作。
LinkedList:LinkedList 使用了双向链表作为底层的数据结构。双向链表可以支持快速的插入和删除操作,但随机访问的性能较差。LinkedList 的每个节点都包含了前驱节点和后继节点的引用。
ConcurrentHashMap (Java SE 11 & JDK 11 ) (runoob.com)
代码随想录算法训练营第六天| 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和_dannky_Z的博客-CSDN博客
代码随想录算法训练营第七天| 454.四数相加II 383. 赎金信15. 三数之和18. 四数之和_dannky_Z的博客-CSDN博客
字符串:
定义:由字母、数字、特殊字符、空格等组成,并使用双引号引用。比如:" ab s j / 12545"
操作:方法调用参考API,常用增加append()/remove()/replace()/charAt()/length()/trim()
String (Java SE 11 & JDK 11 ) (runoob.com)
代码随想录算法训练营第八天 | 344.反转字符串541. 反转字符串II 剑指Offer 05.替换空格151.翻转字符串里的单词剑指Offer58-II.左旋转字符串_dannky_Z的博客-CSDN博客
算法训练Day9| 28. 实现 strStr();459.重复的子字符串;字符串总结 ;双指针回顾_dannky_Z的博客-CSDN博客
栈与队列:
栈:先进后出(后进先出),Stack继承了Vector,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安全的;
队列:先进先出(后进后出),队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。Java在Java中,Queue是个接口,底层是通过链表实现的。
注意: Queue 是个接口,在实例化时必须实例化 LinkedList 的对象,因为 LinkedList 实现了 Queue 接口。
队列的分类:顺序队列、链式队列。
顺序队列:队列的存在形式是队列中的元素是连续的,就像数组。
循环队列:首尾相接的顺序存储队列,顾名思义循环队列就是队列的内存可以循环使用。
链式队列:跟线性表的单链表一样,只是说只能从头出从尾进而已。
双端队列:又名double ended queue,简称deque,双端队列没有队列和栈这样的限制级,它允许两端进行入队和出队操作,也就是说元素可以从队头出队和入队,也可以从队尾出队和入队。
代码训练Day10| 232.用栈实现队列; 225. 用队列实现栈_dannky_Z的博客-CSDN博客
算法训练day11|20. 有效的括号;1047. 删除字符串中的所有相邻重复项;150. 逆波兰表达式求值_dannky_Z的博客-CSDN博客
算法训练Day13|● 239. 滑动窗口最大值● 347.前 K 个高频元素● 总结_dannky_Z的博客-CSDN博客
二叉树:
定义:每个节点有两个子节点,形成类似倒置的树状数据结构。
分类:
1.满二叉树:每个节点有两个直接子节点,且叶子节点是满的。
2.完全二叉树:父节点左子树和右子树之间的高度差小于等于1,且其子节点均居左分布,满二叉树是一种特殊的完全二叉树(左右子树高度差为0,且最底层节点满的状态符合完全二叉树的定义)。
3.二叉搜索树(重点):满足二叉树定义的基础之上,且每个节点存储数值,且该数值有序(父节点的数值大于左子节点及其字节点的数值,小于右子节点及其所有节点上的数值,且其子节点也具有这种规律)。
4.平衡二叉搜索树(AVL 树):在二叉搜索树的基础之上,其左右子树高度差不大于1。
TreeMap:TreeMap 是一个基于红黑树实现的有序映射(键值对)容器。它根据键的自然顺序进行排序,或者根据自定义的 Comparator 进行排序。TreeMap 的插入、删除和查找操作的时间复杂度均为 O(log n)。
TreeSet:TreeSet 是一个基于红黑树实现的有序集合容器。它根据元素的自然顺序进行排序,或者根据自定义的 Comparator 进行排序。TreeSet 的插入、删除和查找操作的时间复杂度均为 O(log n)。
这两个容器都是有序的,且支持高效的插入、删除和查找操作。它们的底层实现都是基于平衡二叉搜索树,因此能够保持元素的有序性,并且具有较快的操作性能。
存储方式:链式存储和顺序存储
链式存储:每个节点存储左右指针和data,每个节点通过指针串联在一起。
顺序存储:底层数据存储在内存是有序连续分布的,也即使用数组。
遍历方式:广度优先遍历、深度优先遍历
广度优先遍历:
层序遍历(迭代法)
深度优先遍历:
前序遍历(递归法、迭代法)
中序遍历(递归法、迭代法)
后续遍历(递归法、迭代法)
前中后序的命名是以中间节点的位置判断的。前序遍历:中左右;中序遍历:左中右;后续遍历:左右中
操作:递归三部曲(有意识的记一下,条件反射的写出来有个框架感,后面回溯的模板类似)
①确定递归方法参数及其返回值
②确定中止条件
③确定单层递归的逻辑
算法训练Day15|理论基础● 递归遍历 ● 迭代遍历● 统一迭代_dannky_Z的博客-CSDN博客
算法训练Day16|● 层序遍历 10 ● 226.翻转二叉树 ● 101.对称二叉树 2_dannky_Z的博客-CSDN博客
算法训练Day17|● 104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数_dannky_Z的博客-CSDN博客
算法训练Day18|● 110.平衡二叉树 ● 257. 二叉树的所有路径 ● 404.左叶子之和_dannky_Z的博客-CSDN博客( 两个Day18不是重复,懒得改了。)算法训练Day18|● 513.找树左下角的值● 112. 路径总和 113.路径总和ii● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树_dannky_Z的博客-CSDN博客
算法训练营Day20| ● 654.最大二叉树 ● 617.合并二叉树 ● 700.二叉搜索树中的搜索 ● 98.验证二叉搜索树_dannky_Z的博客-CSDN博客
算法训练Day21|530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 236. 二叉树的最近公共祖先_dannky_Z的博客-CSDN博客
算法训练Day22|235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点_dannky_Z的博客-CSDN博客
算法训练Day23|669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树_dannky_Z的博客-CSDN博客
回溯:
在一个集合中求子集合、子序列问题。通常将问题拆解为树状结构来处理,通过剪枝的操作进行性优化。下面第一个来链接有详细介绍(这一块的时间复杂度不好计算,很容易迷糊,自己学的不太好)
操作:回溯三步曲
①确定回溯方法参数及其返回值(传参是个技术活)
②确定中止条件
③确定回溯方法的遍历过程
算法训练Day24|理论基础 ● 77. 组合_dannky_Z的博客-CSDN博客
算法训练Day25|216.组合总和III● 17.电话号码的字母组合_dannky_Z的博客-CSDN博客
算法训练Day27|39. 组合总和● 40.组合总和II● 131.分割回文串_dannky_Z的博客-CSDN博客
算法训练Day28|● 93.复原IP地址 ● 78.子集 ● 90.子集II_dannky_Z的博客-CSDN博客
算法训练Day29|* 491.递增子序列* 46.全排列* 47.全排列 II_dannky_Z的博客-CSDN博客
算法训练Day30|● 332.重新安排行程 ● 51. N皇后 ● 37. 解数独_dannky_Z的博客-CSDN博客
贪心:
局部最优,推出整体最优。(思路挺不好想的,多练习形成思维记忆)
算法训练Day31|理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和_dannky_Z的博客-CSDN博客
算法训练Day32|● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II_dannky_Z的博客-CSDN博客
算法训练Day34|1005.K次取反后最大化的数组和 ● 134. 加油站● 135. 分发糖果_dannky_Z的博客-CSDN博客
算法训练Day35|860.柠檬水找零 ● 406.根据身高重建队列 ● 452. 用最少数量的箭引爆气球_dannky_Z的博客-CSDN博客
算法训练Day36|435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间_dannky_Z的博客-CSDN博客
算法训练Day37|738.单调递增的数字 ● 968.监控二叉树_dannky_Z的博客-CSDN博客
动态规划:Day38-Day57
看题量就知道多重要了
dp[]数组的定义、状态转移方程、初始化dp数组(根据状态转移方程来做)、遍历顺序
算法训练Day38|● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯_dannky_Z的博客-CSDN博客
算法训练Day39|62.不同路径 ● 63. 不同路径 II_dannky_Z的博客-CSDN博客
算法训练Day40|343. 整数拆分 ● 96.不同的二叉搜索树_dannky_Z的博客-CSDN博客
算法训练Day41|416. 分割等和子集_dannky_Z的博客-CSDN博客
算法训练Day42|1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零_dannky_Z的博客-CSDN博客
算法练习Day43|● 518. 零钱兑换 II ● 377. 组合总和 Ⅳ_dannky_Z的博客-CSDN博客
算法练习Day44|70. 爬楼梯 (进阶)● 322. 零钱兑换 ● 279.完全平方数_dannky_Z的博客-CSDN博客
算法练习Day46|139.单词拆分_dannky_Z的博客-CSDN博客
算法练习Day48|198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III_dannky_Z的博客-CSDN博客
算法练习Day49|● 121. 买卖股票的最佳时机 ● 122.买卖股票的最佳时机II_dannky_Z的博客-CSDN博客
算法练习Day50|● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV_dannky_Z的博客-CSDN博客
算法修炼Day51|● 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费_dannky_Z的博客-CSDN博客
算法修炼Day52|● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组_dannky_Z的博客-CSDN博客
算法练习Day53|1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和 动态规划_dannky_Z的博客-CSDN博客
算法练习Day55|● 392.判断子序列 ● 115.不同的子序列_dannky_Z的博客-CSDN博客
算法练习Day56|583. 两个字符串的删除操作 ● 72. 编辑距离_dannky_Z的博客-CSDN博客
算法修炼Day57|647. 回文子串 ● 516.最长回文子序列_dannky_Z的博客-CSDN博客
单调栈:
借助栈,设计一个数据结构,使得栈内的数据保持单调递增或单调递减的状态。
算法修炼Day58|● 739. 每日温度 ● 496.下一个更大元素 I_dannky_Z的博客-CSDN博客
算法训练Day59|● 503.下一个更大元素II ● 42. 接雨水_dannky_Z的博客-CSDN博客
算法修炼Day60|● 84.柱状图中最大的矩形_dannky_Z的博客-CSDN博客
2 总结与展望
刷题量:
系统开启刷题的姿势,对数据结构有了基本的认识,但很多操作还不够熟练,保持练习。对题目有了一般性的思考,还不够敏感,需要积累,坚持刷题,希望秋招下来能刷300道(截止到20230828的刷题量,偶尔会参加周赛做个签到题)。
一群朋友:
群里结识了科班已工作的宁哥和同应届很秀的同学,在这对热情的宁哥表示非常的respect!
一点反思:
很多细节因为时间不允许,所以学习的不是很透彻,该画图的没有画图。脑图不是万能的,后面要多动手。
怼点鸡汤:
Don't over think, just be yourself.——Easy