From 7f9363d5ddd85edbb93a391d56aa3b2160818e7a Mon Sep 17 00:00:00 2001 From: roshankumar447 Date: Sat, 7 Nov 2026 20:48:36 +0530 Subject: [PATCH] feat: add ransom-note algorithm with tests --- .../com/thealgorithms/strings/RansomNote.java | 29 ++++++++++++++++ .../thealgorithms/strings/RansomNoteTest.java | 34 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/main/java/com/thealgorithms/strings/RansomNote.java create mode 100644 src/test/java/com/thealgorithms/strings/RansomNoteTest.java diff --git a/src/main/java/com/thealgorithms/strings/RansomNote.java b/src/main/java/com/thealgorithms/strings/RansomNote.java new file mode 100644 index 000000000000..c92e901acaeb --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/RansomNote.java @@ -0,0 +1,29 @@ +package com.thealgorithms.strings; + +/** + * Determines if a ransom note can be constructed using letters from a magazine. + * Each letter in the magazine can only be used once. + * + *

Example: ransomNote = "aa", magazine = "aab" -> true + * + *

Time complexity: O(n), Space complexity: O(1) (fixed 26-char alphabet) + * + * @see LeetCode #383 + */ +public final class RansomNote { + private RansomNote() { + } + + public static boolean canConstruct(String ransomNote, String magazine) { + int[] count = new int[26]; + for (char c : magazine.toCharArray()) { + count[c - 'a']++; + } + for (char c : ransomNote.toCharArray()) { + if (--count[c - 'a'] < 0) { + return false; + } + } + return true; + } +} diff --git a/src/test/java/com/thealgorithms/strings/RansomNoteTest.java b/src/test/java/com/thealgorithms/strings/RansomNoteTest.java new file mode 100644 index 000000000000..5b30159749b1 --- /dev/null +++ b/src/test/java/com/thealgorithms/strings/RansomNoteTest.java @@ -0,0 +1,34 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class RansomNoteTest { + + @Test + public void testCanConstruct() { + assertTrue(RansomNote.canConstruct("aa", "aab")); + } + + @Test + public void testCannotConstruct() { + assertFalse(RansomNote.canConstruct("aa", "ab")); + } + + @Test + public void testEmptyRansomNote() { + assertTrue(RansomNote.canConstruct("", "abc")); + } + + @Test + public void testEmptyMagazine() { + assertFalse(RansomNote.canConstruct("a", "")); + } + + @Test + public void testExactMatch() { + assertTrue(RansomNote.canConstruct("abc", "abc")); + } +}