AI 提示词:力扣算法解题助手

41 浏览
2 试用
0 购买
Oct 12, 2025更新

本提示词专为力扣算法题目解题设计,能够系统化地分析题目需求、拆解解题步骤、提供多种解题思路并生成高效代码实现。通过结构化的问题分析方法,帮助用户深入理解算法本质,提升编程思维能力和代码实现水平。该提示词特别适合准备技术面试、学习数据结构和算法、提升编程能力的开发者使用,能够针对不同难度级别的题目提供针对性的解题指导,从问题分析到代码实现的完整解决方案。

  • 题目分析

    • 给定一个整数数组 nums 和目标值 target,要求找到两个不同的下标 i、j,使得 nums[i] + nums[j] == target,返回任意一组解的下标即可(0 基)。
    • 输入格式:
      • 第一行:整数 n(数组长度)
      • 第二行:n 个整数 nums[i]
      • 第三行:整数 target
    • 输出格式:一行输出两个整数 i j(空格分隔)
    • 约束:
      • 2 <= n <= 1e5
      • -1e9 <= nums[i], target <= 1e9
      • 保证至少存在一组解
    • 重点与边界:
      • 需要返回原始下标,不是排序后的位置
      • 可能存在重复元素
      • 可能存在负数
      • 至少一组解保证存在,算法可以在找到第一组解后立即返回
  • 解题思路

    • 思路一:暴力枚举(双层循环)
      • 对每个 i,检查所有 j > i,若 nums[i] + nums[j] == target 则返回。
      • 时间复杂度 O(n^2),空间复杂度 O(1)。
      • 在 n 可达 1e5 时不可行。
    • 思路二:哈希表一次遍历(最优推荐)
      • 使用字典记录已经遍历过的数值及其索引:map[value] = index。
      • 遍历数组当前值 x,计算补数 c = target - x。
      • 若 c 在字典中,则返回 (map[c], 当前索引);否则将 x 放入字典。
      • 保证不使用同一元素两次,因为只将“之前出现的元素”存入字典。
      • 时间复杂度 O(n),空间复杂度 O(n)。
    • 思路三:排序 + 双指针
      • 将数组元素与索引一起存储为 (value, index) 对,按 value 排序。
      • 用双指针从两端逼近求和,找到满足条件的两个索引。
      • 时间复杂度 O(n log n),空间复杂度 O(n)(存储对)。
      • 缺点:需要额外处理返回原始下标;相较哈希法更慢。
  • 算法设计(选定方案:哈希表一次遍历)

    • 初始化一个空字典 seen,用于记录已遍历过的数字及其下标。
    • 遍历 i 从 0 到 n-1:
      • 令 x = nums[i],计算补数 c = target - x。
      • 若 c 在 seen 中,返回 seen[c] 和 i。
      • 否则,将 seen[x] = i 存入字典。
    • 因为题目保证有解,遍历过程中必然能返回一组下标。
    • 边界与正确性:
      • 当 target = 2*x 且数组中有两个相等的值 x 时:第一次遇到 x 将其存入字典,第二次遇到相同 x 时其补数仍是 x,字典命中返回两个不同的索引。
      • 处理负数和大数对 Python 没有问题,整数无溢出。
  • 代码实现(Python)

import sys

def two_sum(nums, target):
    """
    返回任意一对满足 nums[i] + nums[j] == target 的不同下标 (i, j)。
    使用哈希表实现 O(n) 时间复杂度。
    """
    seen = {}  # value -> index
    for i, x in enumerate(nums):
        c = target - x
        if c in seen:
            return seen[c], i
        # 只在未命中时记录当前值及索引,确保不使用同一元素两次
        seen[x] = i
    # 按题意保证至少有解,这里理论上不会到达
    return -1, -1

def main():
    data = sys.stdin.read().strip().split()
    if not data:
        return
    # 解析输入
    it = iter(data)
    n = int(next(it))
    nums = [int(next(it)) for _ in range(n)]
    target = int(next(it))

    i, j = two_sum(nums, target)
    print(f"{i} {j}")

if __name__ == "__main__":
    main()
  • 复杂度分析

    • 时间复杂度:O(n)
      • 每个元素最多一次哈希查找与一次插入,哈希操作均摊 O(1)。
    • 空间复杂度:O(n)
      • 在最坏情况下需要存储所有已遍历元素的值与索引。
  • 测试用例

    • 基本用例(示例)
      • 输入: 4 2 7 11 15 9
      • 输出:0 1
    • 重复元素
      • 输入: 5 3 3 4 5 6 6
      • 输出:0 1(或 1 0)
    • 负数与零
      • 输入: 5 -1 0 1 2 -2 -1
      • 输出:0 1(-1 + 0 = -1)或 4 2(-2 + 1 = -1)
    • 大数与跨界组合
      • 输入: 3 1000000000 -1000000000 5 5
      • 输出:0 1(1e9 + (-1e9) = 0,不满足;正确应为 2 与某个数 -> 此例请换 target=5)
      • 更正用例: 3 1000000000 -999999995 5 5
      • 输出:0 1(1e9 + (-999999995) = 5)
    • 相同值满足 target = 2*x
      • 输入: 4 5 5 1 9 10
      • 输出:0 1(两个 5 相加等于 10)

题目分析

  • 问题本质:判断有向图是否存在环。课程之间的先修关系构成一个有向图,若图不存在有向环,则可完成所有课程;若存在环,则不可完成。
  • 输入输出:
    • 输入:
      • 第一行:numCourses(课程总数)
      • 第二行:m(先修关系条数)
      • 接下来 m 行:a b,表示课程 a 需要先修课程 b,即有边 b -> a
    • 输出:一行 "true" 或 "false"
  • 约束:
    • 1 <= numCourses <= 1e5
    • 0 <= m <= 2e5
    • 0 <= a, b < numCourses
    • 需要时间复杂度 O(numCourses + m)

解题思路

常见两种方法:

  1. 拓扑排序(Kahn 算法,BFS)

    • 思想:统计每个节点的入度,将入度为 0 的课程入队,逐步“上课”并移除其对后继课程的影响(后继入度减 1)。最终若能处理完所有课程(出队计数等于 numCourses),则无环;否则有环。
    • 优点:迭代实现,无递归栈风险;时间 O(n + m),空间 O(n + m)。
    • 适合本题大规模数据。
  2. DFS 检测环

    • 思想:对每个未访问节点进行 DFS,使用三色标记(0=未访问, 1=访问中, 2=已完成)。在访问中再次遇到访问中的节点,说明存在回边(有向环)。
    • 优点:实现简洁,直观。
    • 缺点:Java 在最坏情况下(长链)可能栈溢出;需注意递归深度限制。

对比与选择:

  • 在本题规模下(最多 1e5 节点、2e5 边),推荐使用 Kahn 拓扑排序(BFS),更稳健,不会栈溢出。DFS 方法可作为参考实现。

算法设计(选定:Kahn 拓扑排序)

  • 数据结构:
    • 邻接表 graph:ArrayList[],graph[u] 存储从 u 指向的后继 v(b -> a)
    • 入度数组 indeg:indeg[v] 表示 v 的入度
    • 队列 queue:存入所有入度为 0 的节点
  • 步骤:
    1. 初始化邻接表和入度数组。
    2. 遍历所有先修关系 (b -> a),填充 graph[b].add(a),并 indeg[a]++。
    3. 将所有入度为 0 的课程入队。
    4. 出队一个课程 u,计数 processed++;遍历 u 的后继 v,执行 indeg[v]--;若 indeg[v] == 0,则入队 v。
    5. 循环结束后,若 processed == numCourses,则返回 true;否则返回 false。
  • 边界情况处理:
    • m == 0:所有课程入度均为 0,直接返回 true。
    • 自环(a == b):会导致 indeg[a] >= 1,最终 processed < numCourses,返回 false。
    • 重边(重复的先修关系):入度会相应累加,拓扑排序正确处理。

代码实现(Java)

说明:

  • 提供两种方法:Kahn(主方法)与 DFS(参考)。
  • 包含 main 方法,按题目输入格式读取并输出结果。
  • 同时提供 LeetCode 风格的 canFinish 方法。
import java.io.*;
import java.util.*;

/**
 * 课程表(是否可修完)
 * 方法一:Kahn 拓扑排序(BFS) —— 推荐
 * 方法二:DFS 检测有向环 —— 参考(可能有递归栈风险)
 */
public class Solution {

    // LeetCode风格函数
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        return canFinishKahn(numCourses, prerequisites);
    }

    // 方法一:Kahn 拓扑排序
    public boolean canFinishKahn(int n, int[][] prerequisites) {
        // 邻接表
        List<Integer>[] graph = new ArrayList[n];
        for (int i = 0; i < n; i++) graph[i] = new ArrayList<>();
        // 入度
        int[] indeg = new int[n];

        // 构图:b -> a
        for (int[] e : prerequisites) {
            int a = e[0], b = e[1];
            graph[b].add(a);
            indeg[a]++;
        }

        // 入度为0的节点入队
        ArrayDeque<Integer> queue = new ArrayDeque<>();
        for (int i = 0; i < n; i++) {
            if (indeg[i] == 0) queue.offer(i);
        }

        int processed = 0;
        while (!queue.isEmpty()) {
            int u = queue.poll();
            processed++;
            for (int v : graph[u]) {
                if (--indeg[v] == 0) {
                    queue.offer(v);
                }
            }
        }

        return processed == n;
    }

    // 方法二:DFS 检测环(参考实现)
    public boolean canFinishDFS(int n, int[][] prerequisites) {
        List<Integer>[] graph = new ArrayList[n];
        for (int i = 0; i < n; i++) graph[i] = new ArrayList<>();
        for (int[] e : prerequisites) {
            int a = e[0], b = e[1];
            graph[b].add(a);
        }
        // 0=未访问, 1=访问中, 2=已完成
        int[] state = new int[n];

        for (int i = 0; i < n; i++) {
            if (state[i] == 0) {
                if (dfsHasCycle(i, graph, state)) {
                    return false; // 有环则不可完成
                }
            }
        }
        return true;
    }

    private boolean dfsHasCycle(int u, List<Integer>[] graph, int[] state) {
        state[u] = 1; // 标记为访问中
        for (int v : graph[u]) {
            if (state[v] == 1) return true;         // 回边:有环
            if (state[v] == 0 && dfsHasCycle(v, graph, state)) return true;
        }
        state[u] = 2; // 完成
        return false;
    }

    // 主程序:按题目输入格式读取并输出
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s;

        s = br.readLine();
        if (s == null) return;
        int numCourses = Integer.parseInt(s.trim());

        s = br.readLine();
        int m = Integer.parseInt(s.trim());

        int[][] prerequisites = new int[m][2];
        for (int i = 0; i < m; i++) {
            String line = br.readLine();
            StringTokenizer st = new StringTokenizer(line);
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            prerequisites[i][0] = a;
            prerequisites[i][1] = b;
        }

        Solution sol = new Solution();
        boolean ans = sol.canFinishKahn(numCourses, prerequisites);
        System.out.println(ans ? "true" : "false");
    }
}

复杂度分析

  • 时间复杂度:
    • 构图 O(n + m)
    • Kahn 拓扑排序遍历每条边一次 O(m),每个节点入队、出队一次 O(n)
    • 总计 O(n + m)
  • 空间复杂度:
    • 邻接表存储 O(n + m)
    • 入度数组 O(n)
    • 队列最多 O(n)
    • 总计 O(n + m)

测试用例

  • 示例1:
    • 输入:
      • numCourses=2, m=1
      • 1 0
    • 输出:true
  • 示例2:
    • 输入:
      • numCourses=2, m=2
      • 1 0
      • 0 1
    • 输出:false
  • 边界用例:
    • 无先修关系:
      • 输入:numCourses=5, m=0
      • 输出:true
    • 自环:
      • 输入:numCourses=1, m=1
      • 0 0
      • 输出:false
    • 长链(压力测试,栈安全性验证对 DFS 不利):
      • 输入:numCourses=5, m=4
      • 1 0
      • 2 1
      • 3 2
      • 4 3
      • 输出:true

说明:在大规模数据下建议采用 Kahn 拓扑排序方案,避免递归带来的栈溢出风险。

题目分析

  • 目标:实现一个支持 get 和 put 操作的 LRU(最近最少使用)缓存。
  • 约束:
    • 容量 cap 与操作数 q 均可达 1e5,需要均摊 O(1) 的操作。
    • 键值可能为负数,范围 [-1e9, 1e9]。
  • 输入输出:
    • 输入 cap 与 q,然后 q 行操作:get k 或 put k v。
    • 输出所有 get 的返回值,每行一个。
  • 核心要求:使用哈希表 + 双向链表 组合,保证均摊 O(1)。

解题思路

  • 暴力(不合格):用数组或链表存键值,每次 get/put 线性查找并维护使用顺序,复杂度 O(n),在 q=1e5 时无法满足性能要求。
  • 标准解(推荐):使用
    • 哈希表(unordered_map):key -> 双向链表节点迭代器,O(1) 查找
    • 双向链表(std::list):维护使用顺序,表头为最近使用,表尾为最久未使用
  • 操作逻辑:
    • get(k):若存在,将节点移至表头并返回值;否则返回 -1
    • put(k, v):
      • 若 k 已存在:更新值并移至表头
      • 若 k 不存在:
        • 容量未满:在表头插入新节点
        • 容量已满:删除表尾节点(LRU),再在表头插入新节点
  • 数据结构选择:
    • 使用 std::list<pair<long long, long long>> 存 (key, value)
    • 使用 unordered_map<long long, list<...>::iterator> 存位置
    • 使用 list::splice 在 O(1) 时间内移动节点到表头

算法设计

  • 维护:
    • list L,头部 L.begin() 为最近使用,尾部 L.back() 为最久未使用
    • unordered_map pos:key -> L 中对应节点迭代器
  • get(key):
    1. 在 pos 中查找;不存在返回 -1
    2. 使用 splice 将该节点移到表头
    3. 返回节点的 value
  • put(key, value):
    1. cap 为 0 时直接返回(防御性处理)
    2. 在 pos 中查找:
      • 若存在:更新节点 value,splice 到表头
      • 若不存在:
        • 若 L.size() == cap:取尾节点,先在 pos 中删除其 key,再 pop_back
        • 在表头 emplace_front 新节点,并在 pos 中记录其迭代器
  • 边界与细节:
    • 负数 key/value 正常支持
    • 多次 put 同一 key,应更新并提升为最近使用
    • 仅 get 输出结果
    • 使用 fast I/O,unordered_map 预留容量以减少 rehash

代码实现(C++)

#include <bits/stdc++.h>
using namespace std;

class LRUCache {
public:
    using K = long long;
    using V = long long;
    using Node = pair<K, V>;

    LRUCache(size_t capacity) : cap(capacity) {
        // 预留哈希表空间,减少 rehash 次数
        pos.reserve(capacity ? capacity : 1);
    }

    int get(K key) {
        auto it = pos.find(key);
        if (it == pos.end()) return -1;
        // 将此节点移动到链表头部(最近使用)
        cache.splice(cache.begin(), cache, it->second);
        return static_cast<int>(it->second->second);
    }

    void put(K key, V value) {
        if (cap == 0) return; // 防御:容量为 0,则不存储任何键

        auto it = pos.find(key);
        if (it != pos.end()) {
            // 更新值并移动到头部
            it->second->second = value;
            cache.splice(cache.begin(), cache, it->second);
            return;
        }

        // 若容量已满,移除尾部(最久未使用)
        if (cache.size() == cap) {
            auto lastIt = prev(cache.end());
            K kEvict = lastIt->first;
            pos.erase(kEvict);
            cache.pop_back();
        }

        // 在头部插入新节点
        cache.emplace_front(key, value);
        pos[key] = cache.begin();
    }

private:
    size_t cap;
    list<Node> cache;                              // 双向链表:头=最近,尾=最久
    unordered_map<K, list<Node>::iterator> pos;    // 哈希:key -> 节点迭代器
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    long long cap;
    int q;
    if (!(cin >> cap)) return 0;
    cin >> q;

    LRUCache lru(static_cast<size_t>(cap));

    for (int i = 0; i < q; ++i) {
        string op;
        cin >> op;
        if (op == "get") {
            long long k;
            cin >> k;
            cout << lru.get(k) << "\n";
        } else if (op == "put") {
            long long k, v;
            cin >> k >> v;
            lru.put(k, v);
        } else {
            // 非法操作名:忽略或可选择处理,这里忽略
        }
    }
    return 0;
}

复杂度分析

  • 时间复杂度:
    • get 与 put 均为均摊 O(1)
      • 哈希查找 O(1) 平均
      • list 的 splice、插入、删除均为 O(1)
  • 空间复杂度:
    • O(cap) 存储双向链表与哈希表

测试用例

  • 示例用例:
    • 输入: 2 9 put 1 1 put 2 2 get 1 put 3 3 get 2 put 4 4 get 1 get 3 get 4
    • 输出: 1 -1 -1 3 4
  • 边界与功能覆盖:
    1. 容量为 1,频繁替换
      • 输入: 1 5 put 1 10 put 2 20 get 1 put 2 30 get 2
      • 期望输出: -1 30
    2. 重复 put 同一键提升最近性
      • 输入: 2 6 put 1 1 put 2 2 put 1 10 put 3 3 get 2 get 1
      • 期望输出: -1 10
    3. 不存在的键
      • 输入: 2 3 put 1 1 get 2 get 1
      • 期望输出: -1 1
    4. 负数键与值
      • 输入: 2 5 put -1 -100 put -2 -200 get -1 put -3 -300 get -2
      • 期望输出: -100 -1
    5. 全是 put(无输出)
      • 输入: 2 3 put 1 1 put 2 2 put 3 3
      • 期望输出:空输出(无行)
    6. 防御性测试:cap=0(若平台允许)
      • 输入: 0 4 put 1 1 get 1 put 2 2 get 2
      • 期望输出: -1 -1

该实现符合题目对 LRU 的期望:哈希表 + 双向链表,操作均摊 O(1),并覆盖常见边界情况。

示例详情

适用用户

技术面试候选人

使用本提示词进行高频题训练,快速梳理题型与话术,生成可讲解代码与测试,用于模拟面试和查漏补缺

计算机相关专业学生

借助结构化分析完成课程作业与实验练习,理解算法原理,输出多语言题解与学习笔记,提升考试与竞赛表现

初入职开发者

用于巩固数据结构与编码规范,在空闲刷题中对照优化建议改进写法,减少线上缺陷并提高评审通过率

解决的问题

为正在刷力扣的学习者与面试候选人打造一套“从读题到通过”的闭环助手:快速读懂题意、拆解解题路径、对比多种方案、生成可运行的高质量代码与测试用例,并给出性能评估与优化建议。以更少时间拿到更多通过记录,形成可复用的解题套路,稳步提升面试通过率与算法思维能力。

特征总结

针对力扣题目一键生成解题流程,从理解需求到代码实现与验证,步骤清晰全程引导
面向不同难度自动匹配解法路径,初学到进阶均可快速上手,明确该做什么与如何做
提供多角度思路对比与取舍建议,轻松看懂暴力与优化差异,迅速锁定更稳更快的方案
一键生成多语言可运行代码与注释,配套测试用例,复制即用,快速验证正确与边界
细致覆盖边界与特殊情况提醒,减少隐藏问题与面试失分,让代码更健壮更可靠
可按个人目标定制输出结构与重点,如面试速记、学习笔记、性能优化清单,满足多场景
内置常见算法模式快速联想,自动识别题型套路,帮助建立系统化刷题与拆解思维
给出效率评估与改进方向,提示可替代策略与优化点,让通过与提速兼得更有把握
支持复盘与改写指导,保留思路脉络与关键步骤,沉淀可迁移的个人题解方法库

如何使用购买的提示词模板

1. 直接在外部 Chat 应用中使用

将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。

2. 发布为 API 接口调用

把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。

3. 在 MCP Client 中配置使用

在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。

AI 提示词价格
¥20.00元
先用后买,用好了再付款,超安全!

您购买后可以获得什么

获得完整提示词模板
- 共 597 tokens
- 3 个可调节参数
{ 题目描述 } { 难度级别 } { 编程语言 }
获得社区贡献内容的使用权
- 精选社区优质案例,助您快速上手提示词
限时免费

不要错过!

免费获取高级提示词-优惠即将到期

17
:
23
小时
:
59
分钟
:
59