I recommend using LeetCode, but smartly (by filtering which questions and not randomly solving them):
- https://neetcode.io/practice
- https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions
- Ensure that you fully understand the problem and the expected output.
- Verify your understanding by asking questions and repeating back what you understand.
- Be honest if you have seen the problem before.
- Do not hesitate to ask any "dumb" questions; the interviewer prefers that you ask rather than make incorrect assumptions.
- Use examples to illustrate and clarify the problem; these can be useful later when testing.
- Start thinking about potential corner cases.
- Determine the size and limit range of inputs and outputs.
- This helps you estimate time and space complexity.
- For large inputs, you may need a more efficient algorithm or data structure.
- Understand the significance of size, such as:
- Length of an array or the size of the expected answer.
- Use limit ranges to identify patterns or constraints that might suggest a simpler solution.
- Begin by considering small, simple examples.
- Use these to identify potential solutions and verify their correctness.
- Consider large examples to evaluate scalability.
- Identify and test edge cases to assess the robustness of your solution.
- Consider the trade-offs between different solutions, prioritizing:
- Correctness.
- Time complexity.
- Space complexity.
- Ease of implementation.
- Code readability.
- Start with a simple, naive solution and evaluate its complexity.
- Identify repeated operations and think about data structures or algorithms that can optimize them.
- Compare multiple possible solutions using time and space complexity to determine which is the most suitable based on the problem's constraints.
- Write code that is easy to read and understand.
- Use meaningful variable and function names, or provide comments if necessary.
- Maintain proper indentation and spacing to enhance readability.
- Test your code with a variety of inputs, including:
- Small inputs for quick checks.
- Edge cases to ensure robustness.
- Walk through your code step-by-step for different scenarios, explaining what happens at each stage.
- Remember to breathe and maintain composure.
- Don't rush; take your time to think through the problem and your solution.