算法模板总结_1_11

非常好,这个节奏是对的,而且是高手在用的节奏 👍
下面我不追求题多,而是把你刚刷完的内容抽象成“可迁移的模板思想”
你以后看到新题,第一反应应该是:“这题套哪个模型?”

我会按你要求的结构来:
👉 算法思想 → 能解决什么问题 → 伪代码 / C 框架


一、快慢指针(Two Pointers – Fast & Slow)

1️⃣ 核心思想(一定要会说)

用两个指针在同一结构中以不同速度前进,
通过它们之间的相对运动关系,解决问题。


2️⃣ 能解决的典型问题

📌 数组 / 字符串

  • 删除元素(原地覆盖)
  • 去重(有序数组)
  • 找满足条件的子序列

📌 链表(复试高频)

  • 判断链表是否有环
  • 找链表中点
  • 删除倒数第 N 个节点

3️⃣ 伪代码 / 思维骨架

A. 数组快慢指针(同向)

slow = 0
for fast in [0..n-1]:
    if fast 满足条件:
        a[slow] = a[fast]
        slow++

👉 本质

  • fast 探路
  • slow 保留有效元素

B. 链表快慢指针(不同速度)

slow = head
fast = head

while fast != NULL and fast->next != NULL:
    slow = slow->next
    fast = fast->next->next

// slow 到达中点

👉 如果 fast 能追上 slow → 有环


4️⃣ C 语言框架示例(链表判环)

int hasCycle(ListNode* head) {
    ListNode* slow = head;
    ListNode* fast = head;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) return 1;
    }
    return 0;
}

5️⃣ 一句话总结(复试可直接说)

快慢指针通过控制指针速度差,
将“相对位置关系”转化为判断条件,
常用于链表结构和原地数组操作。


二、滑动窗口(Sliding Window)

1️⃣ 核心思想

在连续区间上,用一对指针维护一个“窗口”,
随着右指针扩展,左指针按条件收缩,
避免重复计算区间信息


2️⃣ 能解决的问题类型(识别点)

看到这些关键词,第一反应就是滑动窗口

  • 连续子数组 / 子串
  • 最短 / 最长
  • 满足某个条件(和、种类数、频率)

⚠️ 通常要求数组元素非负(否则条件不单调)


3️⃣ 思维骨架(非常重要)

left = 0
for right in [0..n-1]:
    扩大窗口(加入 right)

    while 窗口不满足条件:
        收缩窗口(移出 left)
        left++

    更新答案

👉 右扩左缩,一进一出


4️⃣ C 语言框架(最短子数组和 ≥ target)

int minSubArrayLen(int target, int* a, int n) {
    int left = 0;
    int sum = 0;
    int ans = n + 1;

    for (int right = 0; right < n; right++) {
        sum += a[right];
        while (sum >= target) {
            if (right - left + 1 < ans)
                ans = right - left + 1;
            sum -= a[left++];
        }
    }
    return ans == n + 1 ? 0 : ans;
}

5️⃣ 一句话总结

滑动窗口利用区间条件的单调性
用双指针维护动态区间,
将 O(n²) 降为 O(n)。


三、前缀和(Prefix Sum)

1️⃣ 核心思想

用额外数组预处理区间信息,
将“区间计算”转化为 O(1) 查询


2️⃣ 能解决的问题类型

  • 区间和 / 区间计数
  • 多次查询区间
  • 与哈希表结合(子数组问题)

3️⃣ 思维骨架

prefix[0] = 0
for i in [0..n-1]:
    prefix[i+1] = prefix[i] + a[i]

// 区间 [l, r]
sum = prefix[r+1] - prefix[l]

4️⃣ C 框架

void buildPrefix(int* a, int n, int* pre) {
    pre[0] = 0;
    for (int i = 0; i < n; i++)
        pre[i + 1] = pre[i] + a[i];
}

5️⃣ 一句话总结

前缀和用空间换时间,
适合频繁区间查询的问题。


四、链表反转(复试必背)

1️⃣ 核心思想

在遍历链表的同时,
逐个改变指针方向
用三个指针保存现场。


2️⃣ 能解决的问题

  • 反转整个链表
  • 反转前 N 个节点
  • K 个一组反转(进阶)

3️⃣ 思维骨架

prev = NULL
cur = head
while cur != NULL:
    next = cur->next
    cur->next = prev
    prev = cur
    cur = next

4️⃣ C 框架

ListNode* reverseList(ListNode* head) {
    ListNode* prev = NULL;
    ListNode* cur = head;
    while (cur) {
        ListNode* nxt = cur->next;
        cur->next = prev;
        prev = cur;
        cur = nxt;
    }
    return prev;
}

5️⃣ 一句话总结

链表反转的本质是指针重定向
用三个指针避免链表断裂。


五、链表中的快慢指针(进阶)

1️⃣ 典型用途

  • 找中点
  • 判环
  • 找环入口
  • 删除倒数第 N 个节点

2️⃣ 骨架(找倒数第 N 个)

fast 先走 N 步
slow = head
while fast != NULL:
    fast = fast->next
    slow = slow->next

3️⃣ 思想总结

快慢指针把“距离关系”转化为“同步移动”,
在一次遍历中解决位置问题。


六、数组实现哈希表(复试友好)

1️⃣ 核心思想

当数据范围已知且不大时,
用数组下标直接映射值,
代替复杂哈希结构。


2️⃣ 能解决的问题

  • Two Sum
  • 计数(出现次数)
  • 是否出现过(去重)

3️⃣ 思维骨架

offset = 常量
hash[value + offset] = 信息

4️⃣ C 框架(Two Sum 思路)

#define OFFSET 100000
int hash[200001];

for i in [0..n-1]:
    if hash[target - a[i] + OFFSET] != -1:
        // 找到答案
    hash[a[i] + OFFSET] = i

5️⃣ 一句话总结

数组哈希是以空间换时间
适合数据范围明确、规模可控的情况。


最后一句非常重要的话

模板不是为了背代码,而是为了“看到题就知道用什么”

posted @ 2026-01-18 12:37  Leon_LL  阅读(2)  评论(0)    收藏  举报