diff --git a/Arrays/Hard/FourNumberSum/FourNumberSum.cpp b/Arrays/Hard/FourNumberSum/FourNumberSum.cpp new file mode 100644 index 00000000..1eb5cd1a --- /dev/null +++ b/Arrays/Hard/FourNumberSum/FourNumberSum.cpp @@ -0,0 +1,88 @@ +#include +#include +#include + +std::vector> fourSum(std::vector& num, int target) { + std::vector> res; + + if (num.empty()) { + std::cout << "Input vector is empty. Returning empty result." << std::endl; + return res; + } + + int n = num.size(); + std::sort(num.begin(), num.end()); + + for (int i = 0; i < n; i++) { + // Reduce the problem to finding a 3-sum + int target_3 = target - num[i]; + + for (int j = i + 1; j < n; j++) { + // Reduce the problem to finding a 2-sum + int target_2 = target_3 - num[j]; + + int front = j + 1; + int back = n - 1; + + while (front < back) { + int two_sum = num[front] + num[back]; + + if (two_sum < target_2) front++; + else if (two_sum > target_2) back--; + else { + // Found a valid quadruplet, add to the result + std::vector quadruplet(4, 0); + quadruplet[0] = num[i]; + quadruplet[1] = num[j]; + quadruplet[2] = num[front]; + quadruplet[3] = num[back]; + res.push_back(quadruplet); + + // Processing the duplicates of number 3 + while (front < back && num[front] == quadruplet[2]) ++front; + + // Processing the duplicates of number 4 + while (front < back && num[back] == quadruplet[3]) --back; + } + } + + // Processing the duplicates of number 2 + while (j + 1 < n && num[j + 1] == num[j]) ++j; + } + + // Processing the duplicates of number 1 + while (i + 1 < n && num[i + 1] == num[i]) ++i; + } + + return res; +} + +int main() { + // Read the array elements from STDIN + std::vector v; + int num; + while (std::cin >> num) { + v.push_back(num); + } + + // Check if the input vector is empty + if (v.empty()) { + std::cout << "Input vector is empty. Exiting program." << std::endl; + return 0; + } + + // Read the target sum from STDIN + int target; + std::cin >> target; + + // Find and print the unique quadruplets + std::vector> sum = fourSum(v, target); + std::cout << "Result:" << std::endl; + for (int i = 0; i < sum.size(); i++) { + for (int j = 0; j < sum[i].size(); j++) + std::cout << sum[i][j] << " "; + std::cout << std::endl; + } + + return 0; +} diff --git a/Arrays/Hard/FourNumberSum/FourNumberSum.java b/Arrays/Hard/FourNumberSum/FourNumberSum.java new file mode 100644 index 00000000..73c1ff0c --- /dev/null +++ b/Arrays/Hard/FourNumberSum/FourNumberSum.java @@ -0,0 +1,108 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class Main { + static List> fourSum(int[] arr, int target) { + ArrayList> res = new ArrayList<>(); + + if (arr == null || arr.length == 0) { + System.out.println("Input array is empty or null. Returning empty result."); + return res; + } + + int n = arr.length; + + // Sort the input array in ascending order + Arrays.sort(arr); + + for (int i = 0; i < n; i++) { + // Reduce the problem to finding a 3-sum + int target_3 = target - arr[i]; + + for (int j = i + 1; j < n; j++) { + // Reduce the problem to finding a 2-sum + int target_2 = target_3 - arr[j]; + + int front = j + 1; + int back = n - 1; + + while (front < back) { + int two_sum = arr[front] + arr[back]; + + if (two_sum < target_2) front++; + else if (two_sum > target_2) back--; + else { + // Found a valid quadruplet, add to the result + List quad = new ArrayList<>(); + quad.add(arr[i]); + quad.add(arr[j]); + quad.add(arr[front]); + quad.add(arr[back]); + res.add(quad); + + // Move pointers to avoid duplicates + while (front < back && arr[front] == quad.get(2)) ++front; + while (front < back && arr[back] == quad.get(3)) --back; + } + } + + // Move pointer to avoid duplicates + while (j + 1 < n && arr[j + 1] == arr[j]) ++j; + } + + // Move pointer to avoid duplicates + while (i + 1 < n && arr[i + 1] == arr[i]) ++i; + } + + return res; + } + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + // Read the array elements from STDIN + String[] arrString = scanner.nextLine().split(""); + + // Check if the input array is empty + if (arrString.length == 0) { + System.out.println("Input array is empty. Exiting program."); + scanner.close(); + return; + } + + int[] arr = new int[arrString.length]; + try { + for (int i = 0; i < arrString.length; i++) { + arr[i] = Integer.parseInt(arrString[i]); + } + } catch (NumberFormatException e) { + System.out.println("Invalid input. Please enter valid integers. Exiting program."); + scanner.close(); + return; + } + + // Read the target sum from STDIN + int target; + try { + target = scanner.nextInt(); + } catch (Exception e) { + System.out.println("Invalid input for target sum. Exiting program."); + scanner.close(); + return; + } + + List> result = fourSum(arr, target); + + // Print the result + for (List quad : result) { + for (int num : quad) { + System.out.print(num + " "); + } + System.out.println(); + } + + scanner.close(); + } +} diff --git a/Arrays/Hard/FourNumberSum/FourNumberSum.py b/Arrays/Hard/FourNumberSum/FourNumberSum.py new file mode 100644 index 00000000..2ab4b08d --- /dev/null +++ b/Arrays/Hard/FourNumberSum/FourNumberSum.py @@ -0,0 +1,84 @@ +# Copyrights to venkys.io +# For more programs visit venkys.io +# Python program for FourNumberSum + +#Time Complexity : O(n^k-1) +#Space Complexity : O(n^k-1)+O(k) + +def twosum(arr, target): + """ + Helper function for finding pairs that sum up to the target. + """ + res = [] + low, high = 0, len(arr) - 1 + + while low < high: + # Calculate the current sum of elements at low and high indices + cursum = arr[low] + arr[high] + + # Check conditions to adjust low and high indices + if cursum < target or (low > 0 and arr[low] == arr[low - 1]): + low += 1 + elif cursum > target or (high < len(arr) - 1 and arr[high] == arr[high + 1]): + high -= 1 + else: + # Append the pair to the result and move indices + res.append([arr[low], arr[high]]) + low += 1 + high -= 1 + return res + + +def ksum(arr, target, k): + """ + Main function for finding k elements that sum up to the target. + """ + res = [] + if not arr: + # Return an empty list if the input array is empty + return res + + avg = target // k + + # Check if the average is outside the range of the array + if avg < arr[0] or avg > arr[-1]: + return res + + if k == 2: + # If k is 2, call the twosum function + return twosum(arr, target) + + for i in range(len(arr)): + # Iterate through the array and avoid duplicate elements + if i == 0 or arr[i - 1] != arr[i]: + # Recursive call to find (k-1)-sum in the rest of the array + for s in ksum(arr[i + 1:], target - arr[i], k - 1): + # Append the current element to the solution + res.append([arr[i]] + s) + return res +if __name__ == "__main__": + # Read the array from STDIN + arr_input = input() + target_input = input() + k_input = input() + + # Check if inputs are provided + if not arr_input or not target_input or not k_input: + print("Please provide valid inputs.") + exit() + + try: + # Convert inputs to the required types + arr = list(map(int, arr_input.split())) + target = int(target_input) + k = int(k_input) + except ValueError: + print("Invalid input. Please enter valid numbers.") + exit() + + arr.sort() + # Call the ksum function with the input values + result = ksum(arr, target, k) + + # Print the result + print(result) diff --git a/Arrays/Hard/FourNumberSum/README.md b/Arrays/Hard/FourNumberSum/README.md new file mode 100644 index 00000000..dcd96ece --- /dev/null +++ b/Arrays/Hard/FourNumberSum/README.md @@ -0,0 +1,390 @@ +## Problem Statement - Four Number Sum +Given an array of integers,find anyone combination of four elements in the array whose sum is equal to a given value X. + +## Introduction +The Four Number Sum Problem is a mathematical challenge that involves finding all unique sets of four integers within a given array that add up to a specific target sum. This problem requires algorithmic solutions to efficiently identify and return these sets of four numbers. It is a combinatorial problem that often requires careful consideration of various edge cases and optimization strategies to achieve a solution with optimal time and space complexity. The problem's complexity increases with the size of the input array and the magnitude of the target sum, making it an interesting problem for algorithmic and computational thinking. Efficient solutions to the Four Number Sum Problem can have applications in various fields, including data analysis, cryptography, and optimization. +## Overview +The Four Number Sum Problem involves finding all unique quadruplets within an array that sum up to a given target value. This combinatorial challenge requires devising algorithms that efficiently identify these sets of four numbers. The problem's complexity grows with the size of the input array and the magnitude of the target sum. Efficient solutions are characterized by their ability to handle diverse edge cases and optimize time and space complexity. Applications of solving the Four Number Sum Problem extend to various domains such as data analysis, cryptography, and optimization. As a fundamental problem in algorithmic thinking, addressing it not only hones problem-solving skills but also provides insights into the intricacies of combinatorial challenges within computational domains. +## Code +### Python +```python +# Copyrights to venkys.io +# For more programs visit venkys.io +# Python program for FourNumberSum + +#Time Complexity : O(n^k-1) +#Space Complexity : O(n^k-1)+O(k) + +def twosum(arr, target): + """ + Helper function for finding pairs that sum up to the target. + """ + res = [] + low, high = 0, len(arr) - 1 + + while low < high: + # Calculate the current sum of elements at low and high indices + cursum = arr[low] + arr[high] + + # Check conditions to adjust low and high indices + if cursum < target or (low > 0 and arr[low] == arr[low - 1]): + low += 1 + elif cursum > target or (high < len(arr) - 1 and arr[high] == arr[high + 1]): + high -= 1 + else: + # Append the pair to the result and move indices + res.append([arr[low], arr[high]]) + low += 1 + high -= 1 + return res + + +def ksum(arr, target, k): + """ + Main function for finding k elements that sum up to the target. + """ + res = [] + if not arr: + # Return an empty list if the input array is empty + return res + + avg = target // k + + # Check if the average is outside the range of the array + if avg < arr[0] or avg > arr[-1]: + return res + + if k == 2: + # If k is 2, call the twosum function + return twosum(arr, target) + + for i in range(len(arr)): + # Iterate through the array and avoid duplicate elements + if i == 0 or arr[i - 1] != arr[i]: + # Recursive call to find (k-1)-sum in the rest of the array + for s in ksum(arr[i + 1:], target - arr[i], k - 1): + # Append the current element to the solution + res.append([arr[i]] + s) + return res +if __name__ == "__main__": + # Read the array from STDIN + arr_input = input() + target_input = input() + k_input = input() + + # Check if inputs are provided + if not arr_input or not target_input or not k_input: + print("Please provide valid inputs.") + exit() + + try: + # Convert inputs to the required types + arr = list(map(int, arr_input.split())) + target = int(target_input) + k = int(k_input) + except ValueError: + print("Invalid input. Please enter valid numbers.") + exit() + + arr.sort() + # Call the ksum function with the input values + result = ksum(arr, target, k) + + # Print the result + print(result) +``` +### Step-by-Step Explanation +The provided Python program addresses the Four Number Sum problem, aiming to find all unique sets of four integers within a sorted array that add up to a specified target sum. The code consists of two functions: `twosum` and `ksum`. The `twosum` function serves as a helper to identify pairs in the array that sum up to a given target. It utilizes two pointers, 'low' and 'high,' which traverse the array inwards. The function efficiently skips duplicate elements and adjusts pointers based on the calculated current sum. + +The primary function, `ksum`, tackles the main problem by recursively breaking it down into subproblems. It considers the base case when k equals 2, invoking the `twosum` function to find pairs. For larger values of k, the function iterates through the array, avoiding duplicate elements, and recursively calls itself to find (k-1)-sum in the remaining portion of the array. The results are accumulated in the 'res' list, forming sets of k elements that sum up to the target. + +In the provided example within the `__main__` block, an array [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] is sorted, and the target sum is set to 10. The `ksum` function is called with the parameters of the sorted array, target sum, and the desired k value of 4. The result is then printed, showcasing the unique sets of four numbers that satisfy the specified sum condition. This program demonstrates a systematic approach to solving the Four Number Sum problem in Python. + +### Java +```java +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class Main { + static List> fourSum(int[] arr, int target) { + ArrayList> res = new ArrayList<>(); + + if (arr == null || arr.length == 0) { + System.out.println("Input array is empty or null. Returning empty result."); + return res; + } + + int n = arr.length; + + // Sort the input array in ascending order + Arrays.sort(arr); + + for (int i = 0; i < n; i++) { + // Reduce the problem to finding a 3-sum + int target_3 = target - arr[i]; + + for (int j = i + 1; j < n; j++) { + // Reduce the problem to finding a 2-sum + int target_2 = target_3 - arr[j]; + + int front = j + 1; + int back = n - 1; + + while (front < back) { + int two_sum = arr[front] + arr[back]; + + if (two_sum < target_2) front++; + else if (two_sum > target_2) back--; + else { + // Found a valid quadruplet, add to the result + List quad = new ArrayList<>(); + quad.add(arr[i]); + quad.add(arr[j]); + quad.add(arr[front]); + quad.add(arr[back]); + res.add(quad); + + // Move pointers to avoid duplicates + while (front < back && arr[front] == quad.get(2)) ++front; + while (front < back && arr[back] == quad.get(3)) --back; + } + } + + // Move pointer to avoid duplicates + while (j + 1 < n && arr[j + 1] == arr[j]) ++j; + } + + // Move pointer to avoid duplicates + while (i + 1 < n && arr[i + 1] == arr[i]) ++i; + } + + return res; + } + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + // Read the array elements from STDIN + String[] arrString = scanner.nextLine().split(""); + + // Check if the input array is empty + if (arrString.length == 0) { + System.out.println("Input array is empty. Exiting program."); + scanner.close(); + return; + } + + int[] arr = new int[arrString.length]; + try { + for (int i = 0; i < arrString.length; i++) { + arr[i] = Integer.parseInt(arrString[i]); + } + } catch (NumberFormatException e) { + System.out.println("Invalid input. Please enter valid integers. Exiting program."); + scanner.close(); + return; + } + + // Read the target sum from STDIN + int target; + try { + target = scanner.nextInt(); + } catch (Exception e) { + System.out.println("Invalid input for target sum. Exiting program."); + scanner.close(); + return; + } + + List> result = fourSum(arr, target); + + // Print the result + for (List quad : result) { + for (int num : quad) { + System.out.print(num + " "); + } + System.out.println(); + } + + scanner.close(); + } +} +``` + +### Step-by-Step Explanation +The provided Java program tackles the Four Number Sum problem by identifying all unique quadruplets within an array that sum up to a specified target. The `fourSum` function employs a systematic approach to solving the problem. It initializes an empty ArrayList called `res` to store the resultant quadruplets. The code checks for special cases, ensuring that the input array is valid and not empty. Subsequently, it sorts the array in ascending order using `Arrays.sort(arr)`. + +The main logic is implemented through nested loops. The outer loop iterates through each element of the array, representing the first number in the potential quadruplet. Within this loop, a secondary loop starts from the next element, representing the second number. The problem is then reduced to finding a 2-sum in the remaining array, and two pointers (`front` and `back`) move towards each other to find pairs that satisfy the condition. + +When a valid quadruplet is found, it is added to the result list, and the pointers are adjusted to avoid duplicates. The code also includes mechanisms to skip over duplicate elements, enhancing efficiency. The program completes the search for quadruplets, avoiding unnecessary iterations, and returns the final result. + +In the provided example within the `main` function, an array [1, 0, -1, 0, -2, 2] is used, and the target sum is set to 0. The resulting quadruplets satisfying the sum condition are printed, demonstrating the successful implementation of the Four Number Sum problem-solving approach in Java. + +### CPP +```cpp +#include +#include +#include + +std::vector> fourSum(std::vector& num, int target) { + std::vector> res; + + if (num.empty()) { + std::cout << "Input vector is empty. Returning empty result." << std::endl; + return res; + } + + int n = num.size(); + std::sort(num.begin(), num.end()); + + for (int i = 0; i < n; i++) { + // Reduce the problem to finding a 3-sum + int target_3 = target - num[i]; + + for (int j = i + 1; j < n; j++) { + // Reduce the problem to finding a 2-sum + int target_2 = target_3 - num[j]; + + int front = j + 1; + int back = n - 1; + + while (front < back) { + int two_sum = num[front] + num[back]; + + if (two_sum < target_2) front++; + else if (two_sum > target_2) back--; + else { + // Found a valid quadruplet, add to the result + std::vector quadruplet(4, 0); + quadruplet[0] = num[i]; + quadruplet[1] = num[j]; + quadruplet[2] = num[front]; + quadruplet[3] = num[back]; + res.push_back(quadruplet); + + // Processing the duplicates of number 3 + while (front < back && num[front] == quadruplet[2]) ++front; + + // Processing the duplicates of number 4 + while (front < back && num[back] == quadruplet[3]) --back; + } + } + + // Processing the duplicates of number 2 + while (j + 1 < n && num[j + 1] == num[j]) ++j; + } + + // Processing the duplicates of number 1 + while (i + 1 < n && num[i + 1] == num[i]) ++i; + } + + return res; +} + +int main() { + // Read the array elements from STDIN + std::vector v; + int num; + while (std::cin >> num) { + v.push_back(num); + } + + // Check if the input vector is empty + if (v.empty()) { + std::cout << "Input vector is empty. Exiting program." << std::endl; + return 0; + } + + // Read the target sum from STDIN + int target; + std::cin >> target; + + // Find and print the unique quadruplets + std::vector> sum = fourSum(v, target); + std::cout << "Result:" << std::endl; + for (int i = 0; i < sum.size(); i++) { + for (int j = 0; j < sum[i].size(); j++) + std::cout << sum[i][j] << " "; + std::cout << std::endl; + } + + return 0; +} +``` +### Step-by-Step Explanation +This C++ program addresses the Four Number Sum problem, aiming to find all unique quadruplets within a given vector 'num' that add up to a specified target. The 'fourSum' function employs a systematic approach, starting with sorting the input vector in ascending order, a critical step for efficient solutions. The program then utilizes nested loops to iterate through the vector, considering each element as a potential starting point for the quadruplet. It reduces the problem to finding a 3-sum by subtracting the current element from the target. + +Within the nested loops, the code further reduces the problem to finding a 2-sum, iterating over the remaining elements using two pointers ('front' and 'back'). The pointers traverse the vector towards each other, ensuring unique combinations. When a valid quadruplet is found, it is added to the result vector 'res,' and pointers are adjusted to avoid duplicates efficiently. The code carefully skips over duplicate elements to optimize the search. + +In the 'main' function, a sample vector [1, 0, -1, 0, -2, 2] and a target sum of 0 are used. The 'fourSum' function is called, and the resulting quadruplets are printed. The output displays the unique sets of four numbers that satisfy the specified sum condition, demonstrating the successful implementation of the Four Number Sum problem-solving approach in C++. + +## Time and Space Complexity Analysis +The time and space complexity of the provided Python program for the Four Number Sum problem can be analyzed as follows: + +### Time Complexity: +The time complexity of the program primarily depends on the `ksum` function, which recursively breaks down the problem. Let \(n\) be the length of the input array 'arr.' The main loop iterates through the array, and for each element, a recursive call is made to find \((k-1)\)-sum. In the worst case, the function explores all possible combinations of \(k\) elements, leading to a time complexity of \(O(n^k-1)\). The recursive calls within the loop contribute to the overall time complexity. + +### Space Complexity: +The space complexity is determined by the auxiliary space used during the recursion and the storage of the results. In each recursive call, a new list is created to store the current combination. The depth of the recursion is \(k\), so the maximum stack space required is \(O(k)\). Additionally, the 'res' list accumulates the final result, and in the worst case, it can store \(O(n^k-1)\) combinations. Therefore, the space complexity is \(O(k) + O(n^k-1)\). + +### Summary: +- Time Complexity: \(O(n^k-1)\) +- Space Complexity: \(O(k) + O(n^k-1)\) +## Real-World Applications +1. **Finance and Investment Strategies:** + - In finance, particularly portfolio optimization and risk management, the Four Number Sum problem can be applied to identify combinations of financial assets that collectively meet certain criteria. For instance, investors may look for groups of stocks whose values sum up to a target, representing a balanced and diversified investment. + +2. **Genomic Research:** + - In bioinformatics and genomic research, scientists may use the Four Number Sum problem to identify combinations of genetic markers or sequences that contribute to specific traits or diseases. This can aid in the understanding of complex genetic interactions and the development of personalized medicine. + +3. **Resource Allocation in Supply Chain Management:** + - In supply chain optimization, companies may apply the Four Number Sum problem to allocate resources efficiently. For example, identifying sets of products or components whose combined production or transportation costs meet certain constraints can help optimize the allocation of resources within a supply chain. + +4. **Network Security and Intrusion Detection:** + - In the field of cybersecurity, the Four Number Sum problem can be adapted to analyze network traffic patterns. Detecting combinations of network activities or events that collectively indicate a potential security threat can enhance intrusion detection systems and improve the identification of unusual behavior. + +5. **Chemical Compound Discovery in Drug Development:** + - In pharmaceutical research, scientists can utilize the Four Number Sum problem to explore combinations of chemical compounds that exhibit desired properties for drug development. Identifying sets of compounds whose characteristics sum up to specific criteria can accelerate the process of discovering novel drugs with desired therapeutic effects. + +## Test Cases: + +Test Case 1: +**Input:** +``` +1 0 -1 0 -2 2 +0 +4 +``` + +**Output:** +``` +[[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]] +``` + +**Explanation:** +- The program takes the input array `[1, 0, -1, 0, -2, 2]`, target `0`, and `k = 4`. +- It then sorts the input array. +- Using the `ksum` function, it finds all combinations of `k` elements that sum up to the target. +- In this case, it finds three unique combinations: `[[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]`. +- The program prints the resulting combinations. + +Test Case 2: +**Input:** +``` +3 7 8 10 12 14 +18 +3 +``` + +**Output:** +``` +[[3, 7, 8]] +``` + +**Explanation:** +- The program takes the input array `[3, 7, 8, 10, 12, 14]`, target `18`, and `k = 3`. +- It then sorts the input array. +- Using the `ksum` function, it finds all combinations of `k` elements that sum up to the target. +- In this case, it finds one unique combination: `[[3, 7, 8]]`. +- The program prints the resulting combination. diff --git a/Strings/Easy/ValidPalindrome/Java.md b/Strings/Easy/ValidPalindrome/Java.md new file mode 100644 index 00000000..8b1d2d9b --- /dev/null +++ b/Strings/Easy/ValidPalindrome/Java.md @@ -0,0 +1,102 @@ +# ValidPalindrome + +## Introduction +The Valid Palindrome problem is a common programming challenge that involves determining whether a given string is a valid palindrome. A palindrome is a sequence of characters that reads the same forward as backward, ignoring spaces, punctuation, and capitalization. + +In the Valid Palindrome problem, the task is to create an algorithm or function that can assess whether a given string, when considered as a sequence of alphanumeric characters, is a valid palindrome. This problem often requires handling non-alphanumeric characters and disregarding case to accurately identify palindromic strings. +## Overview +The Valid Palindrome problem entails designing a solution to determine whether a given string is a valid palindrome, considering only alphanumeric characters and ignoring differences in case. The task involves evaluating whether the string reads the same forward and backward after removing non-alphanumeric characters. This problem is a classic exercise in string manipulation and often requires an efficient algorithm to address various edge cases. The solution involves traversing the string from both ends, comparing corresponding characters, and adjusting for case differences and non-alphanumeric characters. The Valid Palindrome problem is frequently encountered in algorithmic interviews and serves as an essential challenge for honing skills in string processing and logical reasoning. +## Code +```java +//Copyrights to venkys.io +//For more programs visit venkys.io +//Java program for ValidPalindrome + +//Time Complexity : O(n) +//Space Complexity : O(1) + +import java.util.Scanner; +public class Main { + + // Function to check if a given string is a palindrome + static boolean isPalindrome(String s) { + String rev = ""; + + // Iterate through each character in the string + for (char ch : s.toCharArray()) { + // Check if the character is a lowercase letter (ASCII values 97 to 122) + if (ch >= 97 && ch <= 122) + rev += ch + ""; + // Check if the character is an uppercase letter (ASCII values 65 to 90) + else if (ch >= 65 && ch <= 90) + // Convert the uppercase letter to lowercase and add it to the 'rev' string + rev += (char) (ch + 32) + ""; + } + + // Initialize two pointers for comparing characters from both ends of the 'rev' string + int i = 0, j = rev.length() - 1; + + // Iterate until the pointers meet in the middle + while (i < j) + // Compare characters at the current positions, and move the pointers accordingly + if (rev.charAt(i++) != rev.charAt(j--)) + return false; + + // If the loop completes without finding any mismatches, the string is a palindrome + return true; + } + + // Main function + public static void main(String[] args) { + // Create a Scanner object to read input from STDIN + Scanner scanner = new Scanner(System.in); + + // Read the input string from STDIN + String s = scanner.nextLine(); + + // Check if the string is a palindrome using the isPalindrome function + if (isPalindrome(s)) + System.out.println("It is a palindrome"); + else + System.out.println("It is not a palindrome"); + + // Close the Scanner object + scanner.close(); + } +} + +``` + +## Step-by-Step Explanation + + +This Java program, adorned with a copyright notice to "venkys.io," checks whether a given string is a palindrome. The `isPalindrome` function begins by initializing an empty string, `rev`, which will store the cleaned version of the input string. It then iterates through each character in the input string, filtering out non-alphabetic characters and converting uppercase letters to lowercase. The cleaned characters are appended to the `rev` string. Two pointers, `i` and `j`, are initialized at the start and end of the cleaned string, respectively. + +The program enters a loop that continues until the pointers meet in the middle of the `rev` string. Within the loop, characters at the current positions pointed to by `i` and `j` are compared. If a mismatch is found, the function returns `false`, indicating that the string is not a palindrome. The pointers are incremented and decremented accordingly. If the loop completes without finding any mismatches, the function returns `true`, indicating that the string is a palindrome. + +In the `main` function, an example string, "A man, a plan, a canal: Panama," is provided, and the program prints whether it is a palindrome or not based on the result of the `isPalindrome` function. This Java program effectively checks for palindromes by considering only alphanumeric characters and ignoring case differences. + +In the example usage, a string `s` is provided: "A man, a plan, a canal: Panama." The `ispalindrome` function is called with this string, and the result is stored in the variable `a`. Finally, the script prints the result using `print(a)`. + +## Time Complexity +The time complexity of the code is O(n), where n is the length of the input string. + +## Space Complexity +The space complexity of the code is O(1) since the additional space used is constant. + +## Real-World Applications + +- **Data Integrity Verification:** + Palindrome checkers are utilized in systems where ensuring data integrity is paramount. They can be employed to verify the accuracy of transmitted or stored data, detecting potential corruption or errors. + +- **Network Communication:** + In network protocols and communication systems, palindromes can be used as a simple but effective method to validate data integrity during transmission, reducing the risk of data corruption. + +- **Coding Interviews and Algorithms:** + Palindrome-related problems are common in coding interviews. Understanding and implementing palindrome checkers are valuable skills for software developers, and the concepts can be applied to various algorithmic challenges. + +- **Crossword Puzzle Validation:** + Palindrome properties are utilized in crossword puzzles where words need to read the same across and down. Palindrome checkers can assist in validating and generating crossword puzzle solutions. + +- **Cryptographic Hash Functions:** + Some cryptographic hash functions leverage palindrome-like properties to enhance security. Palindromic patterns in hashed data contribute to the unpredictability and complexity of the hash. diff --git a/Strings/Easy/ValidPalindrome/Python.md b/Strings/Easy/ValidPalindrome/Python.md new file mode 100644 index 00000000..bd9bb07d --- /dev/null +++ b/Strings/Easy/ValidPalindrome/Python.md @@ -0,0 +1,77 @@ +# ValidPalindrome + +## Introduction +The Valid Palindrome problem is a common programming challenge that involves determining whether a given string is a valid palindrome. A palindrome is a sequence of characters that reads the same forward as backward, ignoring spaces, punctuation, and capitalization. + +In the Valid Palindrome problem, the task is to create an algorithm or function that can assess whether a given string, when considered as a sequence of alphanumeric characters, is a valid palindrome. This problem often requires handling non-alphanumeric characters and disregarding case to accurately identify palindromic strings. +## Overview +The Valid Palindrome problem entails designing a solution to determine whether a given string is a valid palindrome, considering only alphanumeric characters and ignoring differences in case. The task involves evaluating whether the string reads the same forward and backward after removing non-alphanumeric characters. This problem is a classic exercise in string manipulation and often requires an efficient algorithm to address various edge cases. The solution involves traversing the string from both ends, comparing corresponding characters, and adjusting for case differences and non-alphanumeric characters. The Valid Palindrome problem is frequently encountered in algorithmic interviews and serves as an essential challenge for honing skills in string processing and logical reasoning. +## Code +```python +# Copyrights to venkys.io +# For more programs visit venkys.io +# Python program for ValidPalindrome + +# Time Complexity : O(n) +# Space Complexity : O(1) + +def is_palindrome(string): + rev = "" + for char in string: + if char.isalpha(): + rev += char.lower() + + low, high = 0, len(rev) - 1 + while low < high: + if rev[low] != rev[high]: + return False + low += 1 + high -= 1 + return True + +def main(): + # Read the input string from STDIN + s = input( + # Check if the string is a palindrome using the is_palindrome function + result = is_palindrome(s) + # Print the result + if result: + print("It is a palindrome") + else: + print("It is not a palindrome") +if __name__ == "__main__": + main() + +``` + +## Step-by-Step Explanation + + +The `ispalindrome` function begins by initializing an empty string `rev` to store the cleaned version of the input string. It then iterates through each character in the input string using a `for` loop. Within the loop, it checks if each character is alphabetic using the `isalpha()` method. If the character is alphabetic, it is appended to the `rev` string after converting it to lowercase using the `lower()` method. This process effectively filters out non-alphabetic characters and standardizes the case for comparison. + +After cleaning the input string, the function sets up two pointers, `low` and `high`, initialized to the start and end of the cleaned string, respectively. It enters a `while` loop where it compares characters at the positions pointed to by `low` and `high`. If a mismatch is found, indicating that the string is not a palindrome, the function returns `False`. The pointers continue moving towards each other until they meet in the middle. If the loop completes without finding any mismatches, the function returns `True`, indicating that the string is a palindrome. + +In the example usage, a string `s` is provided: "A man, a plan, a canal: Panama." The `ispalindrome` function is called with this string, and the result is stored in the variable `a`. Finally, the script prints the result using `print(a)`. + +## Time Complexity +The time complexity of the code is O(n), where n is the length of the input string. + +## Space Complexity +The space complexity of the code is O(1) since the additional space used is constant. + +## Real-World Applications + +- **Data Integrity Verification:** + Palindrome checkers are utilized in systems where ensuring data integrity is paramount. They can be employed to verify the accuracy of transmitted or stored data, detecting potential corruption or errors. + +- **Network Communication:** + In network protocols and communication systems, palindromes can be used as a simple but effective method to validate data integrity during transmission, reducing the risk of data corruption. + +- **Coding Interviews and Algorithms:** + Palindrome-related problems are common in coding interviews. Understanding and implementing palindrome checkers are valuable skills for software developers, and the concepts can be applied to various algorithmic challenges. + +- **Crossword Puzzle Validation:** + Palindrome properties are utilized in crossword puzzles where words need to read the same across and down. Palindrome checkers can assist in validating and generating crossword puzzle solutions. + +- **Cryptographic Hash Functions:** + Some cryptographic hash functions leverage palindrome-like properties to enhance security. Palindromic patterns in hashed data contribute to the unpredictability and complexity of the hash. diff --git a/Strings/Easy/ValidPalindrome/cpp.md b/Strings/Easy/ValidPalindrome/cpp.md new file mode 100644 index 00000000..88340c26 --- /dev/null +++ b/Strings/Easy/ValidPalindrome/cpp.md @@ -0,0 +1,98 @@ +# ValidPalindrome + +## Introduction +The Valid Palindrome problem is a common programming challenge that involves determining whether a given string is a valid palindrome. A palindrome is a sequence of characters that reads the same forward as backward, ignoring spaces, punctuation, and capitalization. + +In the Valid Palindrome problem, the task is to create an algorithm or function that can assess whether a given string, when considered as a sequence of alphanumeric characters, is a valid palindrome. This problem often requires handling non-alphanumeric characters and disregarding case to accurately identify palindromic strings. +## Overview +The Valid Palindrome problem entails designing a solution to determine whether a given string is a valid palindrome, considering only alphanumeric characters and ignoring differences in case. The task involves evaluating whether the string reads the same forward and backward after removing non-alphanumeric characters. This problem is a classic exercise in string manipulation and often requires an efficient algorithm to address various edge cases. The solution involves traversing the string from both ends, comparing corresponding characters, and adjusting for case differences and non-alphanumeric characters. The Valid Palindrome problem is frequently encountered in algorithmic interviews and serves as an essential challenge for honing skills in string processing and logical reasoning. +## Code +```cpp + +//Copyrights to venkys.io +//For more programs visit venkys.io +//CPP program for ValidPalindrome + +//Time Complexity : O(n) +//Space Complexity : O(1) + +#include +#include + +using namespace std; + +// Function to check if a given string is a palindrome +bool isPalindrome(string s) { + if (s.empty()) { + // If the string is empty, consider it not a palindrome + return false; + } + string rev = ""; + + // Iterate through each character in the string + for (char ch : s) { + // Check if the character is an alphabet letter + if (isalpha(ch)) + rev += tolower(ch); // Convert the character to lowercase and add it to the 'rev' string + } + + // Initialize two pointers for comparing characters from both ends of the 'rev' string + int i = 0, j = rev.length() - 1; + + // Iterate until the pointers meet in the middle + while (i < j) { + // Compare characters at the current positions, and move the pointers accordingly + if (rev[i++] != rev[j--]) return false; + } + + // If the loop completes without finding any mismatches, the string is a palindrome + return true; +} + +// Main function +int main() { + // Read the input string from STDIN + string s; + getline(cin, s); + // Check if the string is a palindrome using the isPalindrome function + if (isPalindrome(s)) + cout << "It is a palindrome"; + else + cout << "It is not a palindrome"; + + return 0; +} + + +``` + +## Step-by-Step Explanation + + +The provided C++ code aims to determine whether a given string is a palindrome by ignoring non-alphanumeric characters and case differences. The `isPalindrome` function begins by iterating through each character in the input string, filtering out non-alphabetic characters, and converting uppercase letters to lowercase. The cleaned characters are stored in the `rev` string. Two pointers, `i` and `j`, are initialized at the start and end of the cleaned string, respectively. The code then enters a loop that compares characters at the current positions pointed to by `i` and `j`. If a mismatch is found, the function returns `false`. The loop continues until the pointers meet in the middle. If the loop completes without finding mismatches, the function returns `true`, indicating that the string is a palindrome. The main function demonstrates this by checking the example string "A man, a plan, a canal: Panama" and prints whether it is a palindrome or not. + + +In the example usage, a string `s` is provided: "A man, a plan, a canal: Panama." The `ispalindrome` function is called with this string, and the result is stored in the variable `a`. Finally, the script prints the result using `print(a)`. + +## Time Complexity +The time complexity of the code is O(n), where n is the length of the input string. + +## Space Complexity +The space complexity of the code is O(1) since the additional space used is constant. + +## Real-World Applications + +- **Data Integrity Verification:** + Palindrome checkers are utilized in systems where ensuring data integrity is paramount. They can be employed to verify the accuracy of transmitted or stored data, detecting potential corruption or errors. + +- **Network Communication:** + In network protocols and communication systems, palindromes can be used as a simple but effective method to validate data integrity during transmission, reducing the risk of data corruption. + +- **Coding Interviews and Algorithms:** + Palindrome-related problems are common in coding interviews. Understanding and implementing palindrome checkers are valuable skills for software developers, and the concepts can be applied to various algorithmic challenges. + +- **Crossword Puzzle Validation:** + Palindrome properties are utilized in crossword puzzles where words need to read the same across and down. Palindrome checkers can assist in validating and generating crossword puzzle solutions. + +- **Cryptographic Hash Functions:** + Some cryptographic hash functions leverage palindrome-like properties to enhance security. Palindromic patterns in hashed data contribute to the unpredictability and complexity of the hash. diff --git a/Strings/Medium/README.md b/Strings/Medium/README.md new file mode 100644 index 00000000..189bb592 --- /dev/null +++ b/Strings/Medium/README.md @@ -0,0 +1,280 @@ +### Problem Statement - Longest Palindromic Substring +Given a string str, the task is to find the longest substring which is a palindrome. +### Introduction +The Longest Palindromic Substring problem is a classic challenge in computer science and algorithm design that focuses on finding the longest contiguous substring within a given string that reads the same backward as forward. This problem is of significant importance in various applications, including DNA sequence analysis, data compression, and text processing. + +The task involves developing an efficient algorithm to determine the length and identify the actual substring that forms the longest palindromic sequence within the given input string. Solving this problem requires a careful exploration of all possible substrings, evaluating their palindromic nature, and optimizing the algorithm for time and space complexity. Researchers and software engineers frequently encounter this problem in interview settings and competitive programming due to its ability to assess a candidate's proficiency in dynamic programming, string manipulation, and algorithmic optimization. The exploration of solutions to the Longest Palindromic Substring problem provides valuable insights into algorithmic thinking and problem-solving skills. +### Overview +The Longest Palindromic Substring problem involves finding the longest contiguous palindrome within a given string. A palindrome is a sequence of characters that reads the same backward as forward. This problem is fundamental in algorithmic design and has applications in various domains, including genetics, data compression, and text analysis. The challenge is to develop an efficient algorithm that can identify and return the longest palindromic substring along with its length. Solutions often employ dynamic programming or expand-around-center techniques to optimize time and space complexity. The problem is frequently encountered in coding interviews and competitive programming, serving as a valuable test of a programmer's ability to navigate string manipulation and algorithmic optimization. +## Code +### Python +```python +#Copyrights to venkys.io +#For more programs visit venkys.io +#Python program for LongestPalindromicSubstring + +# Time Complexity - O(n^2) +# Space Complexity - O(1) + +def expand_from_center(string, left, right): + global max_length + global start + + # Keep expanding while the characters at left and right indices are equal + while left > -1 and right < len(string) and string[left] == string[right]: + left -= 1 + right += 1 + + # Update the maximum length and start index if a longer palindrome is found + if max_length < right - left - 1: + max_length = right - left - 1 + start = left + 1 + +# Initialize global variables max_length and start +global max_length +max_length = 0 + +global start +start = 0 + +def longest_palindrome(string): + global max_length + global start + + # Iterate through each character in the string + for i in range(len(string)): + # Find the length of palindrome when the center is a single character + expand_from_center(string, i, i) + + # Find the length of palindrome when the center is between two characters + expand_from_center(string, i, i + 1) + + # Return the longest palindrome substring using start and max_length + return string[start:start + max_length] + +if __name__ == "__main__": + # Read the input string from STDIN + string = input() + + # Check for null safety + if not string: + print("Input string is empty.") + else: + # Print the longest palindrome in the given string + print(longest_palindrome(string)) + +``` +### Step-by-Step Explanation +The provided Python code defines a function to find the longest palindrome substring within a given string. The main function, `longestPalindrome`, employs a helper function named `expandFromCenter` to iterate through the string, treating each character and the gap between two characters as potential centers of palindromes. + +The `expandFromCenter` function takes three parameters: the input string, and the left and right indices. It then expands outward from the center, checking if the characters at the left and right indices are equal. This process continues as long as the characters are equal and the indices are within the bounds of the string. The function updates global variables, `maxlength` and `start`, to keep track of the length and starting index of the longest palindrome found so far. + +The `longestPalindrome` function iterates through each character in the input string and calls `expandFromCenter` twice for each character: once considering the character as a single-center and once as part of a double-center. The idea is to cover both odd and even-length palindromes. After the iteration, the function returns the longest palindrome substring using the stored `start` and `maxlength` values. + +In the example usage section, the code demonstrates finding the longest palindrome in the string "badab" and prints the result. The provided implementation has a time complexity of O(n^2), where n is the length of the input string, as each expansion process takes linear time. This efficient algorithm allows for the identification of palindromic substrings within a given string. +### Java +```java +// Copyrights to venkys.io +// For more programs visit venkys.io +// Java program for LongestPalindromicSubstring + +// Time Complexity - O(n^2) +// Space Complexity- O(1) + +import java.util.Scanner; + +public class Main { + + // Function to find the longest palindrome in the given string + static String longestPalindrome(String s) { + // Initialize start and end indices for the longest palindrome found + int start = 0, end = 0; + + // Iterate through each character in the string + for (int i = 0; i < s.length(); i++) { + // Find the length of palindrome when the center is a single character + int len1 = expandAroundCenter(s, i, i); + + // Find the length of palindrome when the center is between two characters + int len2 = expandAroundCenter(s, i, i + 1); + + // Find the maximum length between len1 and len2 + int len = Math.max(len1, len2); + + // If the current palindrome is longer than the previous one, update start and end indices + if (len > end - start) { + start = i - (len - 1) / 2; + end = i + len / 2; + } + } + + // Return the longest palindrome substring + return s.substring(start, end + 1); + } + + // Function to expand around the center and find the length of the palindrome + static int expandAroundCenter(String s, int left, int right) { + // Initialize left and right pointers + int L = left, R = right; + + // Keep expanding while the characters at left and right indices are equal + while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) { + L--; + R++; + } + + // Return the length of the palindrome found + return R - L - 1; + } + + // Main method for testing + public static void main(String[] args) { + // Create a Scanner object to read input from STDIN + Scanner scanner = new Scanner(System.in); + + // Read the input string from STDIN + String s = scanner.nextLine(); + + // Check for null safety + if (s.isEmpty()) { + System.out.println("Input string is empty."); + } else { + // Print the longest palindrome in the given string + System.out.println(longestPalindrome(s)); + } + + // Close the Scanner object + scanner.close(); + } +} + +``` +### Step-by-Step Explanation +The provided Java code defines a program to find the longest palindrome substring within a given string. The main function, `longestPalindrome`, initializes indices `start` and `end` to keep track of the current longest palindrome found. It iterates through each character in the input string, treating the character as a potential center of a palindrome, and calls the `expandAroundCenter` function twice for each character. The `expandAroundCenter` function is responsible for expanding outward from the center indices, checking if the characters at the left and right indices are equal, and returning the length of the palindrome found. + +Within the main loop of `longestPalindrome`, the lengths `len1` and `len2` are calculated for the palindromes with single and double centers, respectively. The maximum length between these two is determined using `Math.max(len1, len2)`. If the current palindrome is longer than the previously recorded one, the `start` and `end` indices are updated accordingly. + +After the iteration, the function returns the substring of the input string that corresponds to the longest palindrome, using the updated `start` and `end` indices. In the example usage section, the code demonstrates finding the longest palindrome in the string "badab" and prints the result. The time complexity of the algorithm is O(n^2), where n is the length of the input string, as each expansion process takes linear time. The provided implementation efficiently identifies palindromic substrings within the given string. +### CPP +```cpp +#include +#include +#include + +std::vector> fourSum(std::vector& num, int target) { + std::vector> res; + + if (num.empty()) { + std::cout << "Input vector is empty. Returning empty result." << std::endl; + return res; + } + + int n = num.size(); + std::sort(num.begin(), num.end()); + + for (int i = 0; i < n; i++) { + // Reduce the problem to finding a 3-sum + int target_3 = target - num[i]; + + for (int j = i + 1; j < n; j++) { + // Reduce the problem to finding a 2-sum + int target_2 = target_3 - num[j]; + + int front = j + 1; + int back = n - 1; + + while (front < back) { + int two_sum = num[front] + num[back]; + + if (two_sum < target_2) front++; + else if (two_sum > target_2) back--; + else { + // Found a valid quadruplet, add to the result + std::vector quadruplet(4, 0); + quadruplet[0] = num[i]; + quadruplet[1] = num[j]; + quadruplet[2] = num[front]; + quadruplet[3] = num[back]; + res.push_back(quadruplet); + + // Processing the duplicates of number 3 + while (front < back && num[front] == quadruplet[2]) ++front; + + // Processing the duplicates of number 4 + while (front < back && num[back] == quadruplet[3]) --back; + } + } + + // Processing the duplicates of number 2 + while (j + 1 < n && num[j + 1] == num[j]) ++j; + } + + // Processing the duplicates of number 1 + while (i + 1 < n && num[i + 1] == num[i]) ++i; + } + + return res; +} + +int main() { + // Read the array elements from STDIN + std::vector v; + int num; + while (std::cin >> num) { + v.push_back(num); + } + + // Check if the input vector is empty + if (v.empty()) { + std::cout << "Input vector is empty. Exiting program." << std::endl; + return 0; + } + + // Read the target sum from STDIN + int target; + std::cin >> target; + + // Find and print the unique quadruplets + std::vector> sum = fourSum(v, target); + std::cout << "Result:" << std::endl; + for (int i = 0; i < sum.size(); i++) { + for (int j = 0; j < sum[i].size(); j++) + std::cout << sum[i][j] << " "; + std::cout << std::endl; + } + + return 0; +} + +``` +### Step-by-Step Explanation +The provided C++ program is designed to find the longest palindromic substring in a given string using an efficient algorithm. The `expandFromCenter` function is defined to handle the expansion around a center, taking a string and two indices as input. It iteratively expands outwards from the center indices while the characters at the left and right indices are equal, and it returns the length of the palindrome found. + +The `longestPalindrome` function initializes `start` and `end` indices to keep track of the current longest palindrome found. It iterates through each character in the input string, calling `expandFromCenter` twice for each character: once considering the character as a single center and once as part of a double center. The lengths of the palindromes, `len1` and `len2`, are calculated, and the maximum length between them is determined using `std::max(len1, len2)`. If the current palindrome is longer than the previously recorded one, the `start` and `end` indices are updated accordingly. + +In the `main` function, an example string "badab" is provided, and the `longestPalindrome` function is called to find and print the longest palindromic substring in the given string. The algorithm has a time complexity of O(n^2), where n is the length of the input string, as each expansion process takes linear time. The provided C++ implementation is a concise and effective way to identify and output the longest palindromic substring within a given string. The program includes copyright information and directs users to venkys.io for more programs. + +## Time and Space Complexity Analysis +### Time complexity analysis: + +The time complexity of the provided algorithm is O(n^2), where n is the length of the input string. This is because, for each character in the string, the algorithm expands from the center in two ways: once considering the center as a single character, and once considering the center between two characters. In the worst case, the expansion process may take O(n) time, and since we do this for each of the n characters in the string, the overall time complexity is O(n^2). + +### Space complexity analysis: + +The space complexity of the algorithm is O(1) because it uses a constant amount of extra space, regardless of the size of the input string. The only variables that are used and do not depend on the input size are `maxlength` and `start`, and they are used to keep track of the length and starting index of the longest palindrome found so far. The other variables like `left`, `right`, and the loop index `i` are temporary and do not contribute to the space complexity in a significant way. + +## Real-World Applications +1. **Genomic Sequence Analysis:** + - Identifying the longest palindromic substring is crucial in bioinformatics, especially in genomic sequence analysis. DNA sequences often exhibit palindromic structures, and finding the longest palindromic substring can provide insights into potential functional elements or repeated patterns within the genome. + +2. **Data Compression:** + - Palindromic substrings can be utilized in data compression algorithms. Detecting and encoding repeated palindromic patterns in a string can lead to more efficient compression, reducing the overall size of the data representation. + +3. **Image Processing:** + - In image processing, detecting palindromic structures can be useful for recognizing symmetrical patterns within images. This can be applied in computer vision for tasks such as object recognition, where identifying symmetric features can improve the accuracy of the recognition process. + +4. **Speech Signal Processing:** + - Palindromic patterns may be present in certain speech signals, especially in phonetic or tonal aspects. Analyzing the longest palindromic substrings in speech signals can contribute to speech processing tasks, such as detecting repeated phonemes or patterns in spoken language. + +5. **String Matching and DNA Analysis:** + - Longest palindromic substrings can be employed in string matching algorithms, helping to identify similarities or repetitions in text data. In DNA analysis, palindromic sequences are significant in restriction enzyme recognition sites, which are crucial in genetic engineering and molecular biology techniques like PCR (Polymerase Chain Reaction).