Qwen2.5-7B-Instruct代码生成能力测评LeetCode题目实战最近在尝试用大模型辅助编程学习特别是解决算法题。听说Qwen2.5系列在代码和数学能力上有显著提升尤其是这个7B的指令调优版本号称在编程方面表现不错。正好手头有一些经典的LeetCode题目我就想实际测试一下看看它到底能不能帮我们写出正确的代码甚至还能分析时间复杂度和解题思路。今天这篇文章我就带大家一起来看看Qwen2.5-7B-Instruct在几个不同难度和类型的LeetCode题目上的实际表现。我会把它的解题思路、生成的代码、以及复杂度分析都展示出来看看它是不是真的能成为一个不错的编程学习助手。1. 测试环境与方法在开始之前我先简单说一下我是怎么测试的。我是在本地用Python环境通过Hugging Face的Transformers库加载了Qwen2.5-7B-Instruct模型。为了公平起见所有的提示词prompt我都尽量保持一致的格式先给出题目描述然后明确要求模型用Python写出解决方案并分析时间和空间复杂度。from transformers import AutoModelForCausalLM, AutoTokenizer model_name Qwen/Qwen2.5-7B-Instruct model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypeauto, device_mapauto ) tokenizer AutoTokenizer.from_pretrained(model_name) def generate_code(prompt): messages [ {role: system, content: You are a helpful coding assistant.}, {role: user, content: prompt} ] text tokenizer.apply_chat_template( messages, tokenizeFalse, add_generation_promptTrue ) model_inputs tokenizer([text], return_tensorspt).to(model.device) generated_ids model.generate( **model_inputs, max_new_tokens1024, temperature0.1, do_sampleTrue ) generated_ids [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response tokenizer.batch_decode(generated_ids, skip_special_tokensTrue)[0] return response测试的题目我选了三个不同难度的一个简单的数组题两数之和一个中等难度的链表题反转链表还有一个稍微复杂点的动态规划题爬楼梯。这样能比较全面地看看模型在不同类型问题上的表现。2. 简单题目测试两数之和两数之和应该是LeetCode上最经典的入门题了。题目要求很简单给定一个整数数组和一个目标值找出数组中两个数的和等于目标值并返回它们的下标。我给模型的提示词是这样的请用Python解决以下LeetCode问题 题目两数之和 描述给定一个整数数组nums和一个整数目标值target请你在该数组中找出和为目标值target的那两个整数并返回它们的数组下标。你可以假设每种输入只会对应一个答案并且你不能重复利用这个数组中同样的元素。 要求 1. 写出完整的Python函数解决方案 2. 分析算法的时间复杂度和空间复杂度 3. 如果可能提供解题思路说明2.1 模型生成的解决方案模型给出的回答挺完整的先解释了思路然后给出了代码解题思路 这个问题最直观的解法是使用哈希表在Python中是字典。我们可以遍历数组对于每个元素计算目标值与当前元素的差值然后检查这个差值是否已经在哈希表中。如果在说明我们找到了两个数的和等于目标值如果不在就把当前元素的值和它的索引存入哈希表。 这种方法只需要一次遍历时间复杂度是O(n)空间复杂度也是O(n)因为最坏情况下我们需要存储n个元素到哈希表中。 Python代码实现def twoSum(nums, target): 找出数组中两个数的和等于目标值返回它们的下标 参数: nums: List[int] - 整数数组 target: int - 目标值 返回: List[int] - 两个数的下标 num_map {} # 创建一个空字典来存储数值和索引的映射 for i, num in enumerate(nums): complement target - num # 计算需要的补数 # 如果补数已经在字典中说明找到了两个数 if complement in num_map: return [num_map[complement], i] # 否则将当前数和索引存入字典 num_map[num] i # 根据题目假设总是有解所以这里不会执行 return [] # 测试用例 if __name__ __main__: # 示例1 nums1 [2, 7, 11, 15] target1 9 print(f输入: nums {nums1}, target {target1}) print(f输出: {twoSum(nums1, target1)}) # 应该输出 [0, 1] # 示例2 nums2 [3, 2, 4] target2 6 print(f输入: nums {nums2}, target {target2}) print(f输出: {twoSum(nums2, target2)}) # 应该输出 [1, 2] # 示例3 nums3 [3, 3] target3 6 print(f输入: nums {nums3}, target {target3}) print(f输出: {twoSum(nums3, target3)}) # 应该输出 [0, 1]复杂度分析 - 时间复杂度O(n)其中n是数组的长度。我们只遍历了一次数组每次查找和插入操作在哈希表中的平均时间复杂度是O(1)。 - 空间复杂度O(n)最坏情况下我们需要存储所有n个元素到哈希表中。 这个解法是这个问题的最优解因为我们需要至少遍历一次数组来检查所有可能的组合。2.2 效果评价对于这个简单的题目Qwen2.5-7B-Instruct的表现可以说是相当不错。它给出了正确的哈希表解法这是这个问题的最优解。代码写得很规范有完整的函数文档字符串还包含了测试用例。我特别喜欢它加的注释比如# 计算需要的补数这样的解释对初学者很友好。复杂度分析也准确知道哈希表的操作平均是O(1)时间。不过我也注意到一个小细节它在代码最后说“根据题目假设总是有解所以这里不会执行”然后还是返回了空列表。这个处理其实挺合理的因为题目确实保证有解但为了代码完整性加上这个返回语句也没问题。3. 中等难度测试反转链表接下来我选了一个链表相关的题目——反转链表。这是学习数据结构时很经典的问题也能测试模型对指针操作的理解。我的提示词请用Python解决以下LeetCode问题 题目反转链表 描述给你单链表的头节点head请你反转链表并返回反转后的链表的头节点。 要求 1. 定义链表节点类 2. 写出反转链表的完整Python解决方案 3. 分析算法的时间复杂度和空间复杂度 4. 提供解题思路说明3.1 模型生成的解决方案模型这次先定义了链表节点然后给出了两种解法解题思路 反转链表是一个经典的链表操作问题。主要有两种思路 1. 迭代法使用三个指针prev, curr, next逐个节点反转指向 2. 递归法递归到链表末尾然后从后往前反转 这里我提供迭代法的实现因为它更直观且空间复杂度更低。 Python代码实现# 定义链表节点类 class ListNode: def __init__(self, val0, nextNone): self.val val self.next next def reverseList(head): 反转单链表 参数: head: ListNode - 链表的头节点 返回: ListNode - 反转后的链表的头节点 # 初始化三个指针 prev None # 前一个节点初始为None curr head # 当前节点从头节点开始 # 遍历链表逐个反转节点指向 while curr: # 保存当前节点的下一个节点防止丢失 next_node curr.next # 反转当前节点的指向 curr.next prev # 移动指针prev和curr都向前移动一步 prev curr curr next_node # 循环结束后prev指向新的头节点 return prev def createLinkedList(arr): 根据数组创建链表 if not arr: return None head ListNode(arr[0]) current head for val in arr[1:]: current.next ListNode(val) current current.next return head def printLinkedList(head): 打印链表 result [] current head while current: result.append(current.val) current current.next return -.join(map(str, result)) # 测试用例 if __name__ __main__: # 示例1: [1,2,3,4,5] arr1 [1, 2, 3, 4, 5] head1 createLinkedList(arr1) print(f原始链表: {printLinkedList(head1)}) reversed_head1 reverseList(head1) print(f反转后: {printLinkedList(reversed_head1)}) # 应该输出: 5-4-3-2-1 # 示例2: [1,2] arr2 [1, 2] head2 createLinkedList(arr2) print(f\n原始链表: {printLinkedList(head2)}) reversed_head2 reverseList(head2) print(f反转后: {printLinkedList(reversed_head2)}) # 应该输出: 2-1 # 示例3: [] arr3 [] head3 createLinkedList(arr3) print(f\n原始链表: {printLinkedList(head3)}) reversed_head3 reverseList(head3) print(f反转后: {printLinkedList(reversed_head3)}) # 应该输出: (空)复杂度分析 - 时间复杂度O(n)其中n是链表的长度。我们需要遍历链表中的每个节点一次。 - 空间复杂度O(1)我们只使用了固定的额外空间三个指针没有使用与链表长度相关的额外空间。 迭代法是这个问题的最优解因为它既保证了线性时间复杂度又只需要常数级别的额外空间。3.2 效果评价对于反转链表这个题目Qwen2.5-7B-Instruct的表现依然很稳。它选择了迭代法来实现这是面试时最常要求的方法因为空间复杂度最优。代码写得很清晰三个指针prev、curr、next_node的作用和移动逻辑都很清楚。我特别喜欢它加的注释比如# 保存当前节点的下一个节点防止丢失这种提醒对理解链表操作很重要。它还额外提供了createLinkedList和printLinkedList这两个辅助函数让测试代码更完整。这对于学习者来说很有帮助可以直接运行看到效果。复杂度分析也准确迭代法确实是O(n)时间和O(1)空间。如果它能再提一下递归法的复杂度对比O(n)时间O(n)空间用于递归栈可能会更全面但现在的回答已经足够好了。4. 动态规划测试爬楼梯最后我选了一个经典的动态规划问题——爬楼梯。这个问题虽然标的是简单难度但涉及动态规划的思想能测试模型对算法思维的理解。我的提示词请用Python解决以下LeetCode问题 题目爬楼梯 描述假设你正在爬楼梯。需要n阶你才能到达楼顶。每次你可以爬1阶或2阶。你有多少种不同的方法可以爬到楼顶 要求 1. 写出完整的Python函数解决方案 2. 分析算法的时间复杂度和空间复杂度 3. 解释解题思路特别是动态规划的思想 4. 如果可能提供多种解法并比较4.1 模型生成的解决方案模型这次给出了三种不同的解法解释得挺详细的解题思路 这是一个经典的动态规划问题也可以看作是一个斐波那契数列问题。 思路分析 设dp[i]表示爬到第i阶楼梯的方法数。那么 - 要爬到第i阶可以从第i-1阶爬1阶上来也可以从第i-2阶爬2阶上来 - 所以dp[i] dp[i-1] dp[i-2] - 初始条件dp[0] 1不动算一种方法dp[1] 1只能爬1阶 实际上这就是斐波那契数列1, 1, 2, 3, 5, 8, 13, ... Python代码实现三种方法def climbStairs(n): 爬楼梯问题计算爬到第n阶楼梯的不同方法数 参数: n: int - 楼梯的阶数 返回: int - 不同的方法数 # 方法1动态规划使用数组 def method1_dp_array(n): if n 1: return 1 dp [0] * (n 1) dp[0] 1 # 爬到第0阶有1种方法不动 dp[1] 1 # 爬到第1阶有1种方法爬1阶 for i in range(2, n 1): dp[i] dp[i - 1] dp[i - 2] return dp[n] # 方法2动态规划优化空间只保存前两个状态 def method2_dp_optimized(n): if n 1: return 1 # 只需要保存前两个状态 prev2 1 # dp[i-2]初始为dp[0] prev1 1 # dp[i-1]初始为dp[1] for i in range(2, n 1): current prev1 prev2 # 更新状态为下一轮做准备 prev2 prev1 prev1 current return prev1 # 方法3矩阵快速幂最优时间复杂度 def method3_matrix_power(n): if n 1: return 1 def multiply(a, b): # 2x2矩阵乘法 return [ [a[0][0]*b[0][0] a[0][1]*b[1][0], a[0][0]*b[0][1] a[0][1]*b[1][1]], [a[1][0]*b[0][0] a[1][1]*b[1][0], a[1][0]*b[0][1] a[1][1]*b[1][1]] ] def power(matrix, exp): # 矩阵快速幂 result [[1, 0], [0, 1]] # 单位矩阵 base matrix while exp 0: if exp % 2 1: result multiply(result, base) base multiply(base, base) exp // 2 return result # 斐波那契数列的转移矩阵 matrix [[1, 1], [1, 0]] # 计算matrix的(n-1)次幂 result_matrix power(matrix, n - 1) # F(n) result_matrix[0][0] * F(1) result_matrix[0][1] * F(0) # 其中F(0)1, F(1)1 return result_matrix[0][0] result_matrix[0][1] # 使用优化后的动态规划方法作为主要实现 return method2_dp_optimized(n) # 测试用例 if __name__ __main__: test_cases [0, 1, 2, 3, 4, 5, 10] print(爬楼梯问题测试) print(n\t方法数) print(- * 20) for n in test_cases: result climbStairs(n) print(f{n}\t{result}) # 验证前几个值 print(\n验证) print(fn2时方法数应为211或2{climbStairs(2)}) print(fn3时方法数应为3111, 12, 21{climbStairs(3)}) print(fn4时方法数应为5{climbStairs(4)}) print(fn5时方法数应为8{climbStairs(5)})复杂度分析 方法1动态规划数组 - 时间复杂度O(n)需要计算n个状态 - 空间复杂度O(n)需要存储n1个状态的数组 方法2优化空间动态规划 - 时间复杂度O(n)同样需要计算n个状态 - 空间复杂度O(1)只使用常数空间存储前两个状态 方法3矩阵快速幂 - 时间复杂度O(log n)通过快速幂技术 - 空间复杂度O(1)只使用常数空间 推荐使用方法2它在时间复杂度和空间复杂度之间取得了很好的平衡代码也相对简单易懂。方法3虽然时间复杂度最优但代码较复杂在实际面试或编程中方法2通常是更合适的选择。 这个问题展示了动态规划的核心思想将大问题分解为小问题存储中间结果避免重复计算。爬楼梯问题实际上是斐波那契数列的一个应用在算法学习中具有代表性意义。4.2 效果评价对于爬楼梯这个动态规划问题Qwen2.5-7B-Instruct的表现超出了我的预期。它不仅给出了标准的动态规划解法还提供了三种不同的实现方式并且详细分析了每种方法的复杂度。我特别欣赏它提供的“优化空间动态规划”方法这是面试时最希望看到的写法——O(n)时间O(1)空间。代码中的变量命名也很清晰prev2和prev1分别表示前两个状态容易理解。更让我惊讶的是它居然还给出了矩阵快速幂的解法并且实现了完整的矩阵乘法和快速幂函数。虽然这个解法在面试中不常要求但它展示了模型对算法深度的理解。复杂度分析部分也很全面对比了三种方法的时间和空间复杂度还给出了使用建议。最后总结动态规划思想的部分对学习者很有帮助。5. 综合评估与使用建议通过这三个题目的测试我对Qwen2.5-7B-Instruct的代码生成能力有了比较全面的了解。整体来说它的表现相当不错特别是在算法思路和代码实现方面。优点总结解题思路清晰对于每个问题它都能给出正确的算法思路并且解释得比较清楚适合学习参考。代码质量高生成的代码规范、可读性好有适当的注释和文档字符串。变量命名合理逻辑清晰。复杂度分析准确能够正确分析算法的时间和空间复杂度对于不同解法还能对比分析。考虑全面比如在爬楼梯问题中提供了多种解法在链表问题中提供了辅助函数这些细节做得不错。教育价值回答中包含了算法思想的解释对编程学习者很有帮助。一些局限性当然模型也不是完美的。在更复杂的题目测试中比如图算法或高级动态规划它可能会遇到困难。另外虽然它能生成正确的代码但可能缺乏一些优化技巧或边界情况的特殊处理。使用建议如果你是一个编程学习者用Qwen2.5-7B-Instruct来辅助学习算法是个不错的选择。它可以帮你理解解题思路提供代码参考还能分析复杂度。但要注意它生成的代码不一定总是最优或最简洁的你还需要自己思考和验证。对于面试准备它可以作为一个不错的练习伙伴。你可以自己先尝试解题然后再看看模型的解法对比学习。但不要完全依赖它实际面试中还需要你自己理解和表达。在编程教育中的应用从这次测试来看Qwen2.5-7B-Instruct在编程教育中确实有应用潜力。教师可以用它来生成例题和解答学生可以用它来获取解题思路和代码参考。特别是它的分步解释和复杂度分析对理解算法很有帮助。不过要注意它不能替代教师的指导和学生的独立思考。最好把它当作一个辅助工具而不是答案生成器。6. 总结测试完Qwen2.5-7B-Instruct在LeetCode题目上的表现我的整体感受是挺正面的。这个7B的模型在代码生成方面确实有能力特别是对于常见的数据结构和算法问题它能够给出正确且清晰的解决方案。从两数之和的哈希表解法到反转链表的指针操作再到爬楼梯的动态规划模型都展现出了不错的理解能力和代码实现水平。它不仅会写代码还会解释思路、分析复杂度甚至提供多种解法对比。当然它毕竟是一个7B参数的模型对于特别复杂或新颖的算法问题可能还需要更大的模型或更专门的训练。但就一般性的编程学习和算法练习来说它已经足够好用了。如果你正在学习编程或准备技术面试不妨试试用这样的模型作为辅助工具。但记住最重要的还是自己动手实践、独立思考。模型可以给你参考和启发但真正的理解和掌握还是要靠你自己的练习和总结。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。