diff --git a/src/RansomNote383.java b/src/RansomNote383.java deleted file mode 100644 index 21b0395..0000000 --- a/src/RansomNote383.java +++ /dev/null @@ -1,23 +0,0 @@ -import java.util.HashMap; -import java.util.Map; - -public class RansomNote383 { - public boolean canConstruct(String ransomNote, String magazine) { - Map countR = new HashMap<>(); - char[] charsR = ransomNote.toCharArray(); - for (char c : charsR) { - countR.put(c, countR.getOrDefault(c, 0) + 1); - } - Map countM = new HashMap<>(); - char[] charsM = magazine.toCharArray(); - for (char c : charsM) { - countM.put(c, countM.getOrDefault(c, 0) + 1); - } - for (Map.Entry entry : countR.entrySet()) { - if (countM.getOrDefault(entry.getKey(), 0) < entry.getValue()) { - return false; - } - } - return true; - } -} diff --git a/src/main/java/com/leetcode/easy/RansomNote383.java b/src/main/java/com/leetcode/easy/RansomNote383.java new file mode 100644 index 0000000..639376e --- /dev/null +++ b/src/main/java/com/leetcode/easy/RansomNote383.java @@ -0,0 +1,44 @@ +// Tags: String, Hash Table +package com.leetcode.easy; + +import java.util.HashMap; +import java.util.Map; + +public class RansomNote383 { + /** + * Complexity Analysis: + * Let m = length of magazine, n = length of ransom note, k = number of unique characters. + * Note: k is at most 26 (constant) for lowercase English letters. + *

+ * Time Complexity: O(m) + * - Early return when m < n takes O(1) + * - Building magazine character frequency map: O(m) + * - Building ransom note character frequency map: O(n) + * - Validating character counts by iterating ransom note map: O(n) + * - Total: O(m) + O(n) + O(n) + * - Since we only proceed when m ≥ n, we can simplify: O(m) + O(m) + O(m) = O(m) + *

+ * Space Complexity: O(k) or O(1) + * - Two hash maps store character frequencies, each with at most k unique characters + * - Since k ≤ 26 (constant), can be considered O(1) space + */ + public boolean canConstruct(String ransomNote, String magazine) { + if (ransomNote.length() > magazine.length()) { + return false; + } + Map countR = new HashMap<>(); + for (char c : ransomNote.toCharArray()) { + countR.put(c, countR.getOrDefault(c, 0) + 1); + } + Map countM = new HashMap<>(); + for (char c : magazine.toCharArray()) { + countM.put(c, countM.getOrDefault(c, 0) + 1); + } + for (Map.Entry entry : countR.entrySet()) { + if (countM.getOrDefault(entry.getKey(), 0) < entry.getValue()) { + return false; + } + } + return true; + } +} diff --git a/src/test/java/com/leetcode/easy/RansomNote383Test.java b/src/test/java/com/leetcode/easy/RansomNote383Test.java new file mode 100644 index 0000000..966d21e --- /dev/null +++ b/src/test/java/com/leetcode/easy/RansomNote383Test.java @@ -0,0 +1,46 @@ +package com.leetcode.easy; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class RansomNote383Test { + private RansomNote383 solution; + + @BeforeEach + void setUp() { + solution = new RansomNote383(); + } + + @Test + void testCanConstruct_Example1() { + String ransomNote = "a"; + String magazine = "b"; + + boolean result = solution.canConstruct(ransomNote, magazine); + + assertFalse(result); + } + + @Test + void testCanConstruct_Example2() { + String ransomNote = "aa"; + String magazine = "ab"; + + boolean result = solution.canConstruct(ransomNote, magazine); + + assertFalse(result); + } + + @Test + void testCanConstruct_Example3() { + String ransomNote = "aa"; + String magazine = "aab"; + + boolean result = solution.canConstruct(ransomNote, magazine); + + assertTrue(result); + } +}