热门角色不仅是灵感来源,更是你的效率助手。通过精挑细选的角色提示词,你可以快速生成高质量内容、提升创作灵感,并找到最契合你需求的解决方案。让创作更轻松,让价值更直接!
我们根据不同用户需求,持续更新角色库,让你总能找到合适的灵感入口。
据难度和主题生成高质量编程面试题及解析
给定一个字符串 s,请你找到其中最长的没有重复字符的子串,并返回其长度。
要求:
输入约束:
1 <= len(s) <= 10^5示例 1:
输入: "abcabcbb"
输出: 3
解释: 最长子串是 "abc",它的长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 最长子串是 "b",它的长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 最长子串是 "wke",它的长度为 3。
注意,子串 "pwke" 并不是有效的,因为子串中的字符必须是连续的。
示例 4:
输入: ""
输出: 0
def length_of_longest_substring(s: str) -> int:
# 使用滑动窗口
char_set = set() # 用于存储当前窗口的字符
left = 0 # 左指针,表示窗口的起始位置
max_len = 0 # 记录最长无重复子串的长度
for right in range(len(s)): # 右指针遍历字符串
# 如果字符已经在窗口中,收缩左边界,直到窗口中没有重复字符
while s[right] in char_set:
char_set.remove(s[left])
left += 1
# 将当前字符加入窗口
char_set.add(s[right])
# 更新最大子串的长度
max_len = max(max_len, right - left + 1)
return max_len
问题分析
本题要求找到没有重复字符的最长连续子串。使用滑动窗口技巧,可以高效地解决该问题,将问题从 O(n²) 优化为 O(n)。
滑动窗口解释
left 和 right,分别表示当前考察的子串的起始和结束位置。set 数据结构动态维护。set 中),通过移动左指针缩小窗口大小,直到窗口中没有重复字符。步骤拆解
char_set 用来跟踪窗口中的字符。left 代表滑动窗口的左边界,初始值为 0。right 作为滑动窗口的右边界。char_set,而 char_set 中已经有重复字符,则移动左边界,逐步从窗口中移除字符,直到重复被消除。max_len。边界条件
时间复杂度
right 总共只会从索引 0 移动到 n-1,各字符最多加入窗口一次,因此为 O(n)。left 也最多移动 n 次。空间复杂度
char_set,用于存储窗口范围内的字符。集合的最大大小不会超过输入字符串的字符集规模,最差情况下为 O(k),其中 k 是字符集的大小(如所有 ASCII 字符为 O(128))。n 是字符串长度。这道题考察了滑动窗口、哈希表等经典技巧,意在测试开发者对字符串处理效率的把控能力。解法清晰、高效,是较为常见的中等难度编码面试问题。
给定一个二维网格 grid,其中每个单元格包含一个整数,表示可以获得的金币数量。你可以从网格中的任意一个单元格出发,按照以下规则收集金币:
注意:你可以从任意一个网格中的单元格开始,但在每次路径的采集过程中,不能重复访问同一个单元格。
输入的 grid 是一个大小为 m x n 的二维数组,其中:
grid[i][j] 是一个非负整数,表示该位置的金币数。0 表示该位置无法进入(即不可用,障碍物)。返回一个整数,表示能够收集到的最大金币数量。
输入:
grid =
[
[0, 6, 0],
[5, 8, 7],
[0, 9, 0]
]
输出:
24
解释:
最优路径为从 (1,1) → (1,2) → (2,1) 收集的金币,路径总金币数为 8 + 7 + 9 = 24。
输入:
grid =
[
[1, 0, 7],
[2, 0, 6],
[3, 4, 5],
[0, 3, 0]
]
输出:
28
解释:
最优路径为从 (2,2) → (2,1) → (1,0) → (0,0) 收集的金币,路径金币总数为 5 + 4 + 2 + 1 = 28。
public class MaxGoldCollector {
public int getMaximumGold(int[][] grid) {
int rows = grid.length;
int cols = grid[0].length;
int maxGold = 0;
// Iterate over all cells as potential starting points
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// Start DFS only if the cell contains gold
if (grid[i][j] > 0) {
maxGold = Math.max(maxGold, dfs(grid, i, j));
}
}
}
return maxGold;
}
private int dfs(int[][] grid, int x, int y) {
// Boundary check and obstacle check
if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == 0) {
return 0;
}
// Capture the current cell's gold value and mark it as visited
int currentGold = grid[x][y];
grid[x][y] = 0; // Temporarily mark as visited
// Explore all 4 possible directions (up, down, left, right)
int up = dfs(grid, x - 1, y);
int down = dfs(grid, x + 1, y);
int left = dfs(grid, x, y - 1);
int right = dfs(grid, x, y + 1);
// Restore the current cell's gold (backtracking)
grid[x][y] = currentGold;
// Return the maximum gold collectable from this cell
return currentGold + Math.max(Math.max(up, down), Math.max(left, right));
}
public static void main(String[] args) {
MaxGoldCollector solver = new MaxGoldCollector();
int[][] grid1 = {
{0, 6, 0},
{5, 8, 7},
{0, 9, 0}
};
System.out.println(solver.getMaximumGold(grid1)); // Output: 24
int[][] grid2 = {
{1, 0, 7},
{2, 0, 6},
{3, 4, 5},
{0, 3, 0}
};
System.out.println(solver.getMaximumGold(grid2)); // Output: 28
}
}
设网格的尺寸为 m x n,同时假设平均每个单元格的 DFS 最大深度为 d:
m * n 个单元格。O(m * n * d)。但在实际问题中,d 通常不会太大。O(m * n) 的额外栈空间。因此,空间复杂度为 O(m * n)。
通过这道动态规划与回溯结合的题目,可以有效地考察 Java 开发者在编写递归、处理特殊边界情况以及实现问题优化时的能力。此实现既遵循了清晰的逻辑,又是性能合理的解法。
编写一个递归函数,用于计算一个整数数组中所有元素的和。
要求如下:
arr,以及数组的长度 n。for 或 while)。n == 0),函数应返回 0。输入 1:
arr = [1, 2, 3, 4, 5]
n = 5
输出 1:
15
输入 2:
arr = [10, -2, 3]
n = 3
输出 2:
11
输入 3:
arr = []
n = 0
输出 3:
0
#include <iostream>
#include <vector>
using namespace std;
// 递归函数定义
int recursiveSum(const int arr[], int n) {
// 基本情况:如果数组为空
if (n == 0) {
return 0;
}
// 递归关系:当前元素 + 剩余部分的和
return arr[n - 1] + recursiveSum(arr, n - 1);
}
// 主函数用于测试
int main() {
// 示例输入 1
int arr1[] = {1, 2, 3, 4, 5};
int n1 = sizeof(arr1) / sizeof(arr1[0]);
cout << "Sum of arr1: " << recursiveSum(arr1, n1) << endl;
// 示例输入 2
int arr2[] = {10, -2, 3};
int n2 = sizeof(arr2) / sizeof(arr2[0]);
cout << "Sum of arr2: " << recursiveSum(arr2, n2) << endl;
// 示例输入 3
int arr3[] = {};
int n3 = sizeof(arr3) / sizeof(arr3[0]);
cout << "Sum of arr3: " << recursiveSum(arr3, n3) << endl;
return 0;
}
递归基础:
递归的本质是将一个问题分解为规模更小的子问题,并通过函数的自身调用来解决子问题,逐步返回结果。对于求数组的和问题,可以将数组划分为两部分:最后一个元素和其余数组,问题规模随着数组长度逐步减少,最终变为一个基本情况。
基本情况:
如果数组的长度 n == 0,说明已经没有任何元素,直接返回 0,这是递归的终止条件。
递归关系:
对于任意非空数组,可以将其表示为前 n-1 个元素以及最后一个元素的组合。因此,数组的和为:
recursiveSum(arr, n) = arr[n-1] + recursiveSum(arr, n-1)
递归调用:
每次函数调用会将当前数组的元素 arr[n-1] 加到递归处理结果中。再次调用函数会进一步减少数组的规模,直到触发基本情况,递归返回开始。
举例分析:
对数组 [1, 2, 3, 4, 5],递归调用的过程如下:
recursiveSum(arr, 5)
=> arr[4] + recursiveSum(arr, 4) // 5 + (递归)
=> arr[4] + (arr[3] + recursiveSum(arr, 3)) // 5 + 4 + (递归)
=> arr[4] + (arr[3] + (arr[2] + recursiveSum(arr, 2))) // 5 + 4 + 3 + (递归)
=> arr[4] + (arr[3] + (arr[2] + (arr[1] + recursiveSum(arr, 1)))) // 5 + 4 + 3 + 2 + (递归)
=> arr[4] + (arr[3] + (arr[2] + (arr[1] + (arr[0] + recursiveSum(arr, 0))))) // 5 + 4 + 3 + 2 + 1 + 0
=> 15
时间复杂度:
假设数组的大小为 n,每次递归调用都会减少数组的规模 1,因此递归的深度为 n。每次递归进行一个简单的加法操作,耗时为 O(1)。因此,总时间复杂度为:
O(n)
空间复杂度:
每次递归调用都会在调用栈中创建一个栈帧以存储函数参数和局部变量,因此递归的空间复杂度等同于递归深度。在最坏情况下(数组大小为 n),递归深度为 n。因此,空间复杂度为:
O(n)
3 tighten
帮助技术招聘人员或开发者设计高质量、针对性强的编程面试题以评估应聘者能力,同时为候选人提供学习与练习的资源。通过灵活调整难度、主题和语言,满足从初学者到高级开发者的多样化需求。
快速创建符合岗位需求的编程面试题,帮助公司精准筛选技术候选人,优化招聘效率。
借助自定义难度和主题功能,定制高质量面试题,评估候选人解决实际技术问题的能力。
根据学生水平和课程内容快速生成练习题及解析,助力课堂教学和作业设计。
将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。
把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。
在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。
免费获取高级提示词-优惠即将到期