Two Sum
My Java Journey with LeetCode's Two Sum:
Yo, what’s good? Today, I dove into the Two Sum problem on LeetCode, and it was a wild ride. I’m jotting this down as part of my coding journal to track my thought process, the mistakes I made, and how I cracked it with some help from my virtual coding buddy, Grok. This isn’t just about getting the answer—it’s about learning how to think through problems like a pro. Let’s break it down, Java style!
The Problem
Two Sum is pretty chill at first glance. You’re given an array of integers nums and a target sum, and you need to return the indices of two numbers that add up to the target. For example, if nums = [2, 7, 11, 15] and target = 9, you return [0, 1] because nums[0] + nums[1] = 2 + 7 = 9. The rules? You can’t use the same element twice, and there’s exactly one solution.
My First Stab: Brute-Force with Nested Loops
When I read the problem, my brain was like, “Easy, just check every pair of numbers!” So, my first instinct was to write a nested loop to try every combination of numbers in the array. In Java, that’d look something like:
public int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {for (int j = i + 1; j < nums.length; j++) {if (nums[i] + nums[j] == target) {return new int[] {i, j};}}}
return new int[] {}; // Problem guarantees a solution, so this is just for safety
}
This made sense to me because it’s like manually flipping through every pair of numbers. For nums = [2, 7, 11, 15] and target = 9, it checks:
2 + 7(boom, that’s 9!), and returns[0, 1].
But then I realized this approach is sloooow. With an array of length n, I’m doing roughly n * (n-1) / 2 checks, which is O(n²). If the array’s huge, like thousands of elements, this is gonna crawl. Plus, it felt wasteful—why check every pair when the answer might be right at the start?
My HashMap Idea: Close, But a Big Flaw
I knew I could do better, so I thought, “What about a hashmap? Those are fast for lookups!” My initial plan was:
- Dump all the numbers into a
HashMap. - Loop through the array again, compute
target - nums[i], and check if that difference is in the hashmap.
I figured this would be faster because hashmap lookups are O(1) on average. But then I hit a snag, and I’m glad I caught it. If I add all numbers to the hashmap first, I lose track of the indices properly, and I might accidentally use the same element twice. For example, if nums = [3, 3] and target = 6, I’d find 3 in the hashmap when processing the first 3, but that’s a no-go since the problem says I can’t reuse elements. I was so focused on the numbers that I forgot the output needs to be the indices of the two numbers.
This was a wake-up call. I needed to store number: index pairs in the hashmap to keep track of where each number lives in the array. Back to the drawing board!
The Breakthrough: One-Pass HashMap
After bouncing ideas with Grok, I landed on a slicker approach. Instead of adding all numbers to the hashmap first, I could build the hashmap while looping through the array. Here’s the game plan:
- Loop through the array once.
- For each element
nums[i]:- Calculate the difference:
diff = target - nums[i]. - Check if
diffis in the hashmap. If it is, I’ve got my pair: the index stored inhashmap.get(diff)and the current indexi. - If not, add
nums[i]as the key andias the value to the hashmap.
- Calculate the difference:
This approach is clean because it ensures I never use the same element twice (since I only add nums[i] after checking for the difference). Let’s see it in action with nums = [2, 7, 11, 15] and target = 9:
- Start with an empty hashmap:
{}. - At
i = 0,nums[0] = 2:diff = 9 - 2 = 7.- Is
7in the hashmap? Nope, it’s empty. - Add
2: 0to the hashmap:{2=0}.
- At
i = 1,nums[1] = 7:diff = 9 - 7 = 2.- Is
2in the hashmap? Yup!hashmap.get(2) = 0. - Return
[0, 1].
Done! Found the solution in one pass.
The Java Code
Here’s the final Java code I settled on:
public class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> hashmap = new HashMap<>(); // Key: number, Value: index
for (int i = 0; i < nums.length; i++) {
int diff = target - nums[i];
if (hashmap.containsKey(diff)) {
return new int[] {hashmap.get(diff), i};
}
hashmap.put(nums[i], i);
}
return new int[] {}; // Problem guarantees a solution, so this is just for safety
}
}
Let me explain one line in my own words:
hashmap.put(nums[i], i);
This line adds the current numbernums[i]as a key and its indexias the value to the hashmap. I do this after checking for the difference, so I’m only storing numbers I’ve already processed. This way, if I find a match later, I know it’s from a previous index, avoiding the “same element” trap.
Why This Solution Slaps
This one-pass hashmap approach is fire because:
- Time Complexity: O(n). I loop through the array once, and hashmap operations (
containsKeyandput) are O(1) on average. - Space Complexity: O(n) for storing the hashmap, which is a fair trade for the speed.
- No Double-Dipping: By adding elements to the hashmap after checking for the difference, I ensure I never use the same element twice.
Compared to my brute-force O(n²) idea, this is way faster and more elegant.
Lessons I’m Taking Away
This problem was a goldmine for learning:
- Focus on the Output: I initially got hung up on finding numbers, not indices. Always clarify what the problem wants!
- Edge Cases Matter: My first hashmap idea didn’t handle cases like
nums = [3, 3],target = 6. Writing down edge cases helps catch these bugs early. - Iterate and Optimize: My brute-force solution worked, but it was clunky. Talking through it helped me see the hashmap trick.
- HashMaps Are My New BFF: They’re perfect for problems involving pairs or lookups. I’m already eyeing other problems where this pattern might pop up.
What’s Next for Me
I’m hyped to keep this going. I think I’ll tackle 3Sum or Contains Duplicate next to practice the hashmap pattern more. I’m also loving this journaling thing—it’s like talking to my future self about what I learned. My big takeaway? Don’t just code—think. Break the problem down, talk it out, and let the solution unfold.
Shoutout to Grok for helping me work through this without spoon-feeding me the answer. Here’s to crushing more LeetCode problems and becoming a Java problem-solving beast!
Comments
Post a Comment