September is almost over. It is time to work through LeetCode. I have long said that I would finish it, but never kept the momentum; with October approaching, I hope that three problems a day will get me through the set by year-end. While writing my diary yesterday, I realized that another notebook was nearly full. That reminded me of the many notebooks I have kept since I was seven—perhaps nearly twenty by now. Somehow, the next one feels like the second volume of my life, and I hope it will be a good one. Some competitive programmers look down on LeetCode as too easy; I disagree. Passing a problem may not be difficult, but interviews often require the best time and space complexity, which makes problems involving linked lists and STL design surprisingly demanding. I referred to many discussion threads and CSDN posts while writing these solutions.
I will not document every problem—only the details worth noting. This is a notebook, and I hope to add new insights later.
LeetCode1 Two Sum
Given an array and a target, find two values at different indices whose sum is the target, and return their indices.
If the array were sorted, scan once from both ends. Since it is unsorted, a brute-force solution is $O(n^2)$. Improve it with a map of values already seen, looking up target - current value; return when it is found.
LeetCode3 Longest Substring Without Repeating Characters
Given a string, find its longest substring without repeating characters.
Track the most recent previous position of each character. The distance gives the length of the non-repeating substring ending at the current position; take the maximum.
Given two sorted arrays, return the median of their merged sequence.
The interesting part is repeatedly binary-searching a cut in the shorter array. A median divides the elements into two halves, so the cut position determines the cut in the other array. This gives four boundary values—L1, L2, R1, and R2. Check whether those boundaries are valid, then continue the binary search. A great problem.
The odd/even cases can be handled by multiplying by 2.
$O(n^2)$ brute force; $O(n)$ Manacher’s algorithm. Leaving this for tonight.
This was a review of Manacher’s algorithm. I found this explanation especially clear. When computing each Len[j], the earlier Len[i] values are known; compare rightmost - i with the length at the position symmetric to rightmost, and take the smaller as the initial Len[j].
Pay close attention to trailing zeroes such as 100, negative values, and overflow. I encountered this kind of edge case in a Baidu interview, where it was expected to be considered.
Given a matching rule where . matches any character and * means the preceding character may occur zero or more times.
This problem was painful. I spent a long time untangling the statement: .* can match every character, whereas I initially thought the preceding . had already been fixed.
After that, DP is the natural approach. dp[i][j] represents whether the first $i$ characters can match the first $j$ characters.
The rest is straightforward; the key is *, which requires considering zero, one, or multiple occurrences of its preceding character.