学习笔记:Java刷题心得与高效方法总结
在最近的学习中,我结合豆包MarsCode AI的刷题平台,通过几个编程题目进行了深入的实践。这不仅让我在编程技巧上有所提升,也让我对刷题的方法论和学习规划有了更加清晰的认识。以下是我的一些学习心得、题目解析和计划总结,希望对其他入门同学有所帮助。
一、学习心得:算法思维的训练
在刷题过程中,我发现对每一道题目的解决方案都包含以下几个关键步骤:
- 题意分析:明确题目的需求,找出输入、输出及边界条件。
- 设计思路:分析题目逻辑,画图或列举案例理清楚问题的解题步骤。
- 代码实现:用编程语言实现思路,尤其是细化特殊情况的处理。
- 反复优化:通过调试和运行,改进效率和代码风格。
例如,在解决“计算简单字符串表达式的值”时,我选择了通过栈的机制实现解析器,这是经典的数据结构应用,增强了我的逻辑分解能力。
二、题目解析与代码详解
以下是三个典型题目的详细解析:
1. 基本计算器的实现
题目要求编写一个函数解析和计算带有括号、加减乘除符号的字符串表达式,代码如下:
import java.util.Stack;
public class Main {
public static int solution(String expression) {
Stack<Integer> numbers = new Stack<>();
Stack<Character> operators = new Stack<>();
int i = 0;
while (i < expression.length()) {
char c = expression.charAt(i);
if (Character.isDigit(c)) {
int num = 0;
while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
num = num * 10 + (expression.charAt(i) - '0');
i++;
}
numbers.push(num);
continue;
} else if (c == '+' || c == '-' || c == '*' || c == '/') {
while (!operators.isEmpty() && precedence(c) <= precedence(operators.peek())) {
numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
}
operators.push(c);
} else if (c == '(') {
operators.push(c);
} else if (c == ')') {
while (operators.peek() != '(') {
numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
}
operators.pop();
}
i++;
}
while (!operators.isEmpty()) {
numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
}
return numbers.pop();
}
private static int precedence(char operator) {
switch (operator) {
case '+':
case '-': return 1;
case '*':
case '/': return 2;
default: return 0;
}
}
private static int applyOperation(char operator, int b, int a) {
switch (operator) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
return 0;
}
public static void main(String[] args) {
System.out.println(solution("1+1") == 2);
System.out.println(solution("3+4*5/(3+2)") == 7);
}
}
在实现中,利用两个栈分别保存操作数和操作符,配合优先级规则高效地完成表达式求值。
2. 最大值函数与数组分析
这道题目通过栈实现了复杂的索引匹配逻辑,充分体现了数据结构在算法题中的作用。代码如下:
import java.util.Stack;
public class Main {
public static int solution(int n, int[] array) {
int[] L = new int[n];
int[] R = new int[n];
Stack<Integer> stackL = new Stack<>();
for (int i = 0; i < n; i++) {
while (!stackL.isEmpty() && array[stackL.peek()] <= array[i]) {
stackL.pop();
}
L[i] = stackL.isEmpty() ? 0 : stackL.peek() + 1;
stackL.push(i);
}
Stack<Integer> stackR = new Stack<>();
for (int i = n - 1; i >= 0; i--) {
while (!stackR.isEmpty() && array[stackR.peek()] <= array[i]) {
stackR.pop();
}
R[i] = stackR.isEmpty() ? 0 : stackR.peek() + 1;
stackR.push(i);
}
int maxValue = 0;
for (int i = 0; i < n; i++) {
int maxI = L[i] * R[i];
maxValue = Math.max(maxValue, maxI);
}
return maxValue;
}
public static void main(String[] args) {
System.out.println(solution(5, new int[]{5, 4, 3, 4, 5}) == 8);
}
}
3. DNA最小编辑距离
利用动态规划的思想解决最小编辑距离问题,代码如下:
public class Main {
public static int solution(String dna1, String dna2) {
int len1 = dna1.length();
int len2 = dna2.length();
int[][] dp = new int[len1 + 1][len2 + 1];
for (int i = 0; i <= len1; i++) {
dp[i][0] = i;
}
for (int j = 0; j <= len2; j++) {
dp[0][j] = j;
}
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (dna1.charAt(i - 1) == dna2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = Math.min(dp[i - 1][j] + 1, Math.min(dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1));
}
}
}
return dp[len1][len2];
}
public static void main(String[] args) {
System.out.println(solution("AGCTTAGC", "AGCTAGCT") == 2);
}
}
三、总结与建议
-
高效学习计划:
- 明确目标:每天刷题数量设为2-3题,兼顾不同难度。
- 专项练习:针对弱项(如动态规划)集中解决经典题型。
- 记录错题:分析错误原因,总结规律以便复习。
-
工具与资源结合:
- 使用豆包MarsCode AI推荐的题目进行逐步难度提升。
- 利用网络资源(如LeetCode讨论区)和纸笔画图辅助理解。
通过坚持刷题,我感受到算法学习的成就感,也期待未来通过更多实践进一步提升!