I have a related question. When I try to do 'interview questions', I usually get stumped (I'm not really into math). In all the project Euler type problems that I've attempted, I find myself continuously using the Brute-force approach, only to find someone's very clever (and in hindsight, obvious) method to do the same. Or usually, I'll google the problem to find how someone else approached it, and only after I've studied it, or just 'took a peek', will I attempt my own solution.
Now, I've studied Algorithms and data structures, and it's not that I'm bad at algorithms. I can understand well defined (aka classic) algorithms just fine, but I find it really hard to find (or create!) patterns in numbers and to manipulate them in order to solve a complex problem.
When attempting a problem that has an obvious brute force solution ask yourself why the brute force solution is wasteful. "It is wasteful because if I've already compared element A and element B, and I've already compared element B and element C then in some cases I shouldn't need to compare element C and element A." Is the type of thinking you should be having. This will lead you towards the right data structures and algorithms. Also, understanding sets and set theory really helps too.
1) Start with a brute force solution, and then look for optimizations. A good way to do this is have it print out (or display in some form) each of its guesses. You will almost allways see it do something stupid, at which point you found an optimization.
2) Write downs as many observations about the problem as you can; if possible, write them down in mathematical notation. See what you can find by combining observations.
3) If you have some sense of what a solution might look like, write it down and see where it goes; don't wait until you think you have the entire answer.
4) When you look at other people algorithms, as soon as you see them do something you didn't, put there paper to the side, do what they did, and see where you can take it on your own.
5) If what you are doing looks related to a subject you are not fammilar with, research that subject.
6) Similarly, if you can reduce a problem (or sub-problem) to another one, but you have no idea how to solve the new one, research to see if people have already solved your new one.
7) If you every see a sequence of numbers, go here: http://oeis.org/
7b) If the only description in oeis is a link to the Project Euler problem you are solving, then this technique is probably to cheety.
8) Invent to variables/functions
9) Math notation is there to help you, make up your own if it expresses the problem more cleanly.
10) Never right a false statement on your work paper unless it is clearly indicated by words like "assume" or "not".
10b) If you see a statement on one of your papers, assume that it is true even if you forgot why.
Thank you for writing that. I've been struggling with this for quite a while and your pointers can help me be someone more clever than a brute-force code-monkey. :)
More specifically, divide your practice problems into two categories before you start working on them. Category A - don't peek. Category B - do peek, and try to learn from others. Category A will ultimately be where the real learning occurs.
Now, I've studied Algorithms and data structures, and it's not that I'm bad at algorithms. I can understand well defined (aka classic) algorithms just fine, but I find it really hard to find (or create!) patterns in numbers and to manipulate them in order to solve a complex problem.
Any suggestions on how can I improve myself?