最近刷算法的一些心得~

最近刷算法的一个心得(说不定哪天就又换想法了呢hh,唯一的不变就是变化本身,现在还是一个算法菜鸡,欢迎指正~),大抵就是觉得

text
复制代码
算法这个东西不是智商游戏,是肌肉记忆

这里说的算法是一个正常的非算法岗位的算法,如果再缩小一点范围的话,就当我说的是力扣 hot 100 吧

1. 之前为什么 "坚持" 下来

这次刷算法算是 "坚持" 下来了吧,大概有一个多月的时间了,中间当然也断过,但整体上来说还是在刷的,而且感觉不是苦哈哈的那种,我也在想之前的时候为什么没有 "坚持" 下来呢?

1. 顺序

之前具体怎么刷的我记得不是特别的清晰了,大概就是按照算法导航的推荐学习路线啃的

排序 -> 查找 -> 字符串匹配 -> 递归与分治......

会把算法算法其下的子算法展开,比如排序当中的归并,快排等等,每个都提供思路,时间复杂度,如何理解,不同编程语言的实现方式,最后会有一些力扣的练习题,这个练习题待会也是我要吐槽的点

这个顺序有什么问题呢?它是以算法为导向的,但当我们说起算法的时候,全称一般是什么:“数据结构和算法”,数据结构是在前面的,算法简单来说是什么呢?是实现某个功能的思路,蛮多时候思路是有一些的,至少对于一些简单题是的,但还是写不出来,是为什么呢?以及为什么总是使用暴力穷举呢?

我觉得原因是同一个,对于数据结构就不熟练,拿力扣的第一题——两数之和来说,暴力穷举的时间复杂度是 O(N²),用哈希来做时间复杂度就是 O(N),但一个算法新手怎么会想到这些呢?

在我看来刷算法之前,先补的应该是数据结构,基本的数据结构,数组,链表,栈,哈希,树这些

算法的学习顺序用学数据结构的学习顺序,对于我来说是效果更好的

image.png

2. 提供的力扣题目

提供的力扣题目怎么说呢?给我的感觉就是跨度是有些太大了,且强度是不小的,对于一个像我这样的傻瓜,就导致就算前面的算法硬着头皮啃下来了(自我感觉的那种),实际做题的时候,做不出来,收到的多数都是负反馈

3. 现在

就是对于上面两点的修正吧,从学习数据结构的顺序出发,力扣的题目结合自己的情况去做,保证在自己的能力边缘区伸展,目前的反馈还是不错的,一天大概会刷一个多小时,刷刷之前的老题,熟悉语法 + 顺思路,很多时候就是在做老题的时候有了新的理解;再精做一道两道新的题目,以题目难度为准

2. 算法题到底怎么刷呢?

现在算法题对于我来说是分为下面的三个部分的

1. 原子方法

原子方法就是那些跨题目通用的代码碎片,因为是这些是跨题目的,是通用的,所以这就具备了复利效应,积累下来就会越刷越顺,之前的我是没有去整理过这些内容的,一道题做完就是做完了,顶多会把某一个算法,比如快排当做一个最小单位,不会再继续拆分了,我知道过去真的很傻

比如今天刷的 "最长连续序列" 当中两个,再比如二分查找当中的 mid = left + (right - left) / 2 这个求中间值的公式,二分查找迭代的终止条件 if (left <= right) 等等这些都是

  • 微积木 A:全量哈希去重 (The Loader)

    • 功能:是否存在 + 去重

    • 语法修复HashSet 只需要一个泛型(只有 Key,没有 Value)

    Java
    复制代码
    // 放入 Set:O(N) Set<Integer> set = new HashSet<>(); for (int num : nums) set.add(num);
  • 微积木 B:龙头剪枝器 (The Pruner)

    • 作用核心中的核心。只有当自己是“头”时,才允许启动计数。

    • 复利价值:解决所有“避免重复计算子序列”的问题。

    • 代码

    Java
    复制代码
    // 只有当 num-1 不存在时,说明 num 是起点,才开始干活 if (!set.contains(num - 1)) { int currentNum = num; int count = 1; // 一口气数到底 while (set.contains(currentNum + 1)) { currentNum++; count++; } // 更新最大值 maxLen = Math.max(maxLen, count); }

2. 数据结构

积累这些数据结构的物理极限,也就是其时间复杂度和空间复杂度;

因为一些题目是会对时间复杂度或者空间复杂度之类的进行限制的,比如时间复杂度要求 O(N),那肯定要和暴力穷举说拜拜了;比如空间复杂度要求上要求 O(1),那就不能创建一个新的数组,链表之类的了,哈希映射也不能用了

适用场景和代价 & 副作用。 看到哪些特征使用什么数据结构,比如涉及到暂存的操作,那么基本就指向了栈这个数据结构;至于副作用,比如在使用 HashSet 的时候是用空间换时间,但是如果数据量极大(几亿个),内存就爆(HashSet 开销大),比如哈希冲突,虽然理论上是 O(1),但数据如果发生哈希冲突,性能会退化,但是在力扣判题上通常忽略

这部分的内容在刷面试题的时候也会呼应到,尤其是哈希这个数据结构,当然像数组,链表,树这些都是经常使用的数据结构,在深入原理的时候是避不开的,所以刷算法不是只在刷算法

3. 算法思想

像是递归,分而治之,归并,排序,剪枝,双指针(当然指针又可以分为快慢指针,对撞指针,排序 + 双指针,滑动窗口这些),回溯算法等等

这些内容也是可以跨题目的,是通用的,是有复利效应的,依然拿今天的 "最长连续序列" 举例子,这个算法题重要的算法思想就是 "剪枝",就可以有下面的这些问题来深入这个思想,主要就是核心思想和应用场景,第三个和第四个是在学的过程当中想到的

"剪枝" 的核心思想是什么? 什么时候可以应用 "剪枝" ? "剪枝" 和去重的区别是什么? "剪枝" 和 if 判断的区别是什么?

4. 到底如何刷算法呢?

我现在是这样的,在刷完一个算法之后,除了上面的三个部分,我还会加上一个力扣习题的部分,就核心本质相同的题目进行一个拓展,这个沉淀下来的内容,我称之为 "算法碎片"

现在在刷算法的过程反馈还是挺足的,因为明确的知道这件事情是有复利效应的,且及时性比较强,就像在收集一块又一块的积木,你还能通过这些收集到的积木来搭建出来新的东西

相关的提示词我放到下面了,其实很简单,主要还是看自己怎么做

text
复制代码
Gemini,从现在开始,我们启动【交互式·沉淀协议 3.3(终极详细版)】 ### **第一步:侦探直觉(由我输入)** 1. **表面信号**:题目特征。 2. **隐藏内核**:底层物理公理。 ### **第二步:助手审计(由你输出)** 必须包含我的原始输入。输出风格要求**详尽、深入、教学导向**。 #### **0. 侦探手记 (档案回溯)** * **表面信号**:[引用我的原始输入] * **隐藏内核**:[引用我的原始输入] #### **1. 内核验证与升维** * **侦探直觉评价**:评价我的理解深度,指出盲区或亮点。 * **升维结论**:用“架构师语言”总结底层规律。使用 ==高亮== 强调核心定义。 #### **2. 积木审计:数据结构篇(物理极限)** * **物理极限**:详细解释时间/空间复杂度的来源。 * **适用场景**:详细描述触发该方案的信号特征。 * **代价与副作用**:深入分析为了效率牺牲了什么(如内存连续性、写入性能等)。 #### **3. 原子方法:越小越强的微积木** * 提取 2-3 个跨题目通用的 Java 代码片段。 * **复利价值**:详细解释为什么要背这个片段,它解决了什么通用问题。 #### **4. 实战映射:隐藏场景的具象化(马甲题)** * **逻辑叙事**:用生活比喻重述算法动态。 * **马甲题映射**: * **马甲一:[标题]** * 🔗 [链接] 提供可以直达的力扣链接 * **表面差异**:它伪装成了什么。 * **内核映射**:为什么它本质还是这个逻辑。
0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
花萍雨
下载 APP