diff --git a/algorithms-and-data-structures/src/main/java/com/xtenzq/arrays/TwoPointers.java b/algorithms-and-data-structures/src/main/java/com/xtenzq/arrays/TwoPointers.java index f534942..f7502a3 100644 --- a/algorithms-and-data-structures/src/main/java/com/xtenzq/arrays/TwoPointers.java +++ b/algorithms-and-data-structures/src/main/java/com/xtenzq/arrays/TwoPointers.java @@ -2,6 +2,13 @@ public class TwoPointers { + /** + * Checks if the given string is a palindrome. + * + * @param input the string to check for palindrome properties + * @return {@code true} if the input string is a palindrome, false otherwise + * @implNote This method runs in {@code O(n)} time complexity and {@code O(1)} space complexity, where n is the length of the input string. + */ public static boolean isPalindrome(String input) { int start = 0; int end = input.length() - 1; @@ -15,6 +22,14 @@ public static boolean isPalindrome(String input) { return true; } + /** + * Checks if there are two distinct elements in the sorted array that sum up to the given target. + * + * @param sortedArray an array of integers that is already sorted in ascending order + * @param target the sum to find in the array + * @return {@code true} if there are two distinct elements in the array whose sum is equal to the target, {@code false} otherwise + * @implNote This method runs in {@code O(n)} time complexity and {@code O(1)} space complexity, where n is the length of the sortedArray. + */ public static boolean canBeSummed(int[] sortedArray, int target) { int start = 0; int end = sortedArray.length - 1; @@ -31,4 +46,42 @@ public static boolean canBeSummed(int[] sortedArray, int target) { } return false; } + + /** + * Merges two sorted arrays into one sorted array. + * + * @param arr1 the first sorted array + * @param arr2 the second sorted array + * @return a new sorted array containing all elements from both input arrays + * @implNote This method runs in {@code O(n + m)} time complexity and {@code O(1)} space complexity, + * where {@code n} is the length of {@code arr1} and {@code m} is the length of {@code arr2}. + */ + public static int[] mergeSortedArrays(int[] arr1, int[] arr2) { + int[] res = new int[arr1.length + arr2.length]; + int i = 0, j = 0, k = 0; + while (i < arr1.length && j < arr2.length) { + if (arr1[i] < arr2[j]) { + res[k] = arr1[i]; + i++; + } else { + res[k] = arr2[j]; + j++; + } + k++; + } + + while (i < arr1.length) { + res[k] = arr1[i]; + i++; + k++; + } + + while (j < arr2.length) { + res[k] = arr2[j]; + j++; + k++; + } + + return res; + } } diff --git a/algorithms-and-data-structures/src/test/java/com/xtenzq/arrays/TwoPointersTest.java b/algorithms-and-data-structures/src/test/java/com/xtenzq/arrays/TwoPointersTest.java index 500eabb..2e357d8 100644 --- a/algorithms-and-data-structures/src/test/java/com/xtenzq/arrays/TwoPointersTest.java +++ b/algorithms-and-data-structures/src/test/java/com/xtenzq/arrays/TwoPointersTest.java @@ -2,27 +2,191 @@ import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static com.xtenzq.arrays.TwoPointers.canBeSummed; +import static com.xtenzq.arrays.TwoPointers.isPalindrome; +import static com.xtenzq.arrays.TwoPointers.mergeSortedArrays; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; class TwoPointersTest { @Test - void shouldReturnTrueIfPalindrome() { - assertTrue(TwoPointers.isPalindrome("racecar")); + void testEmptyString() { + assertTrue(isPalindrome("")); } @Test - void shouldReturnFalseIfNotPalindrome() { - assertFalse(TwoPointers.isPalindrome("raceacar")); + void testSingleCharacter() { + assertTrue(isPalindrome("a")); } @Test - void shouldReturnTrueIfCanBeSummed() { - assertTrue(TwoPointers.canBeSummed(new int[] { 1, 2, 4, 6, 8, 9, 14, 15 }, 13)); + void testSimplePalindrome() { + assertTrue(isPalindrome("madam")); } @Test - void shouldReturnFalseIfCantBeSummed() { - assertFalse(TwoPointers.canBeSummed(new int[] { 1, 2, 4, 6, 8, 9, 14, 15 }, 30)); + void testSimpleNonPalindrome() { + assertFalse(isPalindrome("hello")); + } + + @Test + void testPalindromeWithSpaces() { + assertTrue(isPalindrome("a man a plan a canal panama".replace(" ", ""))); + } + + @Test + void testNonPalindromeWithSpaces() { + assertFalse(isPalindrome("hello world")); + } + + @Test + void testPalindromeWithMixedCase() { + assertTrue(isPalindrome("Able was I ere I saw Elba".replace(" ", "").toLowerCase())); + } + + @Test + void testPalindromeWithPunctuation() { + assertTrue(isPalindrome("A man, a plan, a canal, Panama".replaceAll("[\\W]", "").toLowerCase())); + } + + @Test + void testNonPalindromeWithPunctuation() { + assertFalse(isPalindrome("Hello, world!")); + } + + @Test + void testEmptyArray() { + int[] array = {}; + int target = 5; + assertFalse(canBeSummed(array, target)); + } + + @Test + void testSingleElementArray() { + int[] array = {5}; + int target = 5; + assertFalse(canBeSummed(array, target)); + } + + @Test + void testTwoElementsSumToTarget() { + int[] array = {1, 4}; + int target = 5; + assertTrue(canBeSummed(array, target)); + } + + @Test + void testTwoElementsDoNotSumToTarget() { + int[] array = {1, 2}; + int target = 5; + assertFalse(canBeSummed(array, target)); + } + + @Test + void testMultipleElementsSumToTarget() { + int[] array = {1, 2, 3, 4, 5}; + int target = 9; + assertTrue(canBeSummed(array, target)); + } + + @Test + void testMultipleElementsDoNotSumToTarget() { + int[] array = {1, 2, 3, 4, 5}; + int target = 10; + assertFalse(canBeSummed(array, target)); + } + + @Test + void testSumWithNegativeNumbers() { + int[] array = {-3, -1, 1, 2, 4}; + int target = 1; + assertTrue(canBeSummed(array, target)); + } + + @Test + void testNegativeTarget() { + int[] array = {-5, -3, -1, 2, 4}; + int target = -4; + assertTrue(canBeSummed(array, target)); + } + + @Test + void testNoPossibleSum() { + int[] array = {1, 2, 3, 4, 5}; + int target = 20; + assertFalse(canBeSummed(array, target)); + } + + @Test + void testZeroTarget() { + int[] array = {-2, -1, 0, 1, 2}; + int target = 0; + assertTrue(canBeSummed(array, target)); + } + + @Test + void testMergeBothEmptyArrays() { + int[] arr1 = {}; + int[] arr2 = {}; + int[] expected = {}; + assertArrayEquals(expected, mergeSortedArrays(arr1, arr2)); + } + + @Test + void testMergeFirstArrayEmpty() { + int[] arr1 = {}; + int[] arr2 = {1, 2, 3}; + int[] expected = {1, 2, 3}; + assertArrayEquals(expected, mergeSortedArrays(arr1, arr2)); + } + + @Test + void testMergeSecondArrayEmpty() { + int[] arr1 = {1, 2, 3}; + int[] arr2 = {}; + int[] expected = {1, 2, 3}; + assertArrayEquals(expected, mergeSortedArrays(arr1, arr2)); + } + + @Test + void testMergeBothNonEmpty() { + int[] arr1 = {1, 3, 5}; + int[] arr2 = {2, 4, 6}; + int[] expected = {1, 2, 3, 4, 5, 6}; + assertArrayEquals(expected, mergeSortedArrays(arr1, arr2)); + } + + @Test + void testMergeArraysWithDuplicates() { + int[] arr1 = {1, 3, 5, 5}; + int[] arr2 = {2, 4, 5, 6}; + int[] expected = {1, 2, 3, 4, 5, 5, 5, 6}; + assertArrayEquals(expected, mergeSortedArrays(arr1, arr2)); + } + + @Test + void testMergeArraysWithNegativeNumbers() { + int[] arr1 = {-3, -1, 2}; + int[] arr2 = {-2, 0, 3}; + int[] expected = {-3, -2, -1, 0, 2, 3}; + assertArrayEquals(expected, mergeSortedArrays(arr1, arr2)); + } + + @Test + void testMergeArraysWithDifferentLengths() { + int[] arr1 = {1, 2, 3, 4, 5}; + int[] arr2 = {6, 7}; + int[] expected = {1, 2, 3, 4, 5, 6, 7}; + assertArrayEquals(expected, mergeSortedArrays(arr1, arr2)); + } + + @Test + void testMergeArraysWithSameElements() { + int[] arr1 = {1, 1, 1}; + int[] arr2 = {1, 1, 1}; + int[] expected = {1, 1, 1, 1, 1, 1}; + assertArrayEquals(expected, mergeSortedArrays(arr1, arr2)); } } \ No newline at end of file