Two Sum: From JavaScript to C# - A Developer's Translation Guide
As developers, we often find ourselves working across different programming languages, and translating algorithms from one language to another is a common challenge. Today, we'll explore the classic Two Sum problem and see how to implement it in both JavaScript and C#, highlighting the key differences and potential pitfalls when making the transition.
Given an array of integers nums
and an integer target
, return the indices of the two numbers that add up to the target. You may assume that each input has exactly one solution, and you may not use the same element twice.
Example:
Input: nums = [2,7,11,15], target = 9 Output: [0, 1] Explanation: nums[0] + nums[1] = 2 + 7 = 9
Javascript Implementation
function twoSum(nums, target) { const map = new Map(); for (let i = 0; i < nums.length; i++) { const complement = target - nums[i]; if (map.has(complement)) { return [map.get(complement), i]; } map.set(nums[i], i); } return []; }
C# Implementation
public class Solution { public int[] TwoSum(int[] nums, int target) { Dictionary<int, int> map = new Dictionary<int, int>(); for (int i = 0; i < nums.Length; i++) { int complement = target - nums[i]; if (map.ContainsKey(complement)) { return new int[] { map[complement], i }; } map[nums[i]] = i; } return new int[] {}; } }
So, now it is time to highlight the key differences.
1. Data Types and Type Declaration
Javascript
const map = new Map(); const complement = target - nums[i];
C#
Dictionary<int, int> map = new Dictionary<int, int>(); int complement = target - nums[i];
2. Hash Table / Dictionary Operations
Operation | Javascript(Map) | C# (Dictionary) |
---|---|---|
Check if key exists | map.has(key) | map.ContainsKey(key) |
Get value | map.get(key) | map[key] |
Set value | map.set(key, value) | map[key] = value |
3. Array Properties
Javascript
nums.length // lowercase 'l'
C#
nums.Length // uppercase 'L'
4. Array Initialization
Javascript
return [map.get(complement), i]; // Array literal return []; // Empty array
C#
return new int[] { map[complement], i }; // Typed array initialization return new int[] {}; // Empty typed array
5. Function/Method Structure
JavaScript:
- Standalone function
- Dynamic return type
- Flexible parameter types
C#:
- Method within a class
- Explicit return type (
int[]
) - Strongly typed parameters (
int[] nums, int target
)
Common Pitfalls When Translating
Common mistakes
// Wrong - JavaScript-style syntax in C# Dictionary<number, number> map; // 'number' doesn't exist in C# if (map.has(complement)) // Should be ContainsKey() return [map.get(complement), i]; // Wrong array syntax nums.length // Should be nums.Length
Correct C# synatx
Dictionary<int, int> map = new Dictionary<int, int>(); if (map.ContainsKey(complement)) return new int[] { map[complement], i }; nums.Length
Performance Comparison
Both implementations have identical time and space complexity:
- Time Complexity: O(n) - single pass through the array
- Space Complexity: O(n) - hash table storage
The performance difference is negligible for this algorithm, as both languages optimize hash table operations well.
Alternative C# Approaches
Using LINQ (Less Efficient)
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[] {}; }
Using TryGetValue (Slightly More Efficient)
public int[] TwoSum(int[] nums, int target) { Dictionary<int, int> map = new Dictionary<int, int>(); for (int i = 0; i < nums.Length; i++) { int complement = target - nums[i]; if (map.TryGetValue(complement, out int complementIndex)) { return new int[] { complementIndex, i }; } map[nums[i]] = i; } return new int[] {}; }
Key Takeaways for JavaScript → C# Translation
- Embrace Strong Typing: Specify types explicitly - it helps catch errors early
- Learn the API Differences: Map vs Dictionary methods are different
- Case Sensitivity Matters: length vs Length, method naming conventions
- Array Initialization: Use new type[]{} instead of []
- Class Structure: C# methods typically live within classes
Never forget the semi-colon in C#, the code won't compile.
Conclusion
While the core algorithmic logic remains identical between JavaScript and C#, the syntax and type system differences require careful attention. Understanding these patterns will make you more effective when working across both languages. The Two Sum problem is an excellent starting point for practicing language translation skills, as it covers fundamental concepts like arrays, hash tables, and iteration patterns that appear frequently in both languages.
Pro Tip
: When translating algorithms, focus on the logic first, then adapt the syntax. The problem-solving approach stays the same, only the implementation details change!