青训营X豆包MarsCode 技术训练营第四篇| 豆包MarsCode AI 刷题”

94 阅读3分钟

学习笔记:Java刷题心得与高效方法总结

在最近的学习中,我结合豆包MarsCode AI的刷题平台,通过几个编程题目进行了深入的实践。这不仅让我在编程技巧上有所提升,也让我对刷题的方法论和学习规划有了更加清晰的认识。以下是我的一些学习心得、题目解析和计划总结,希望对其他入门同学有所帮助。

一、学习心得:算法思维的训练

在刷题过程中,我发现对每一道题目的解决方案都包含以下几个关键步骤:

  1. 题意分析:明确题目的需求,找出输入、输出及边界条件。
  2. 设计思路:分析题目逻辑,画图或列举案例理清楚问题的解题步骤。
  3. 代码实现:用编程语言实现思路,尤其是细化特殊情况的处理。
  4. 反复优化:通过调试和运行,改进效率和代码风格。

例如,在解决“计算简单字符串表达式的值”时,我选择了通过栈的机制实现解析器,这是经典的数据结构应用,增强了我的逻辑分解能力。

二、题目解析与代码详解

以下是三个典型题目的详细解析:

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);
    }
}

三、总结与建议

  1. 高效学习计划

    • 明确目标:每天刷题数量设为2-3题,兼顾不同难度。
    • 专项练习:针对弱项(如动态规划)集中解决经典题型。
    • 记录错题:分析错误原因,总结规律以便复习。
  2. 工具与资源结合

    • 使用豆包MarsCode AI推荐的题目进行逐步难度提升。
    • 利用网络资源(如LeetCode讨论区)和纸笔画图辅助理解。

通过坚持刷题,我感受到算法学习的成就感,也期待未来通过更多实践进一步提升!