diff --git a/dsa-solutions/gfg-solutions/Easy problems/square-root.md b/dsa-solutions/gfg-solutions/Easy problems/square-root.md index c249e2811..f0c2eb177 100644 --- a/dsa-solutions/gfg-solutions/Easy problems/square-root.md +++ b/dsa-solutions/gfg-solutions/Easy problems/square-root.md @@ -1,193 +1,193 @@ ---- -id: square-root -title: Square Root -sidebar_label: Square-Root -tags: - - Math - - Binary Search -description: "This document provides solutions to the problem of finding the Square Root of an integer." ---- - -## Problem - -Given an integer `x`, find the square root of `x`. If `x` is not a perfect square, then return the floor value of √x. - -### Examples - -**Example 1:** - -``` -Input: x = 5 -Output: 2 -Explanation: Since 5 is not a perfect square, the floor of the square root of 5 is 2. -``` - -**Example 2:** - -``` -Input: x = 4 -Output: 2 -Explanation: Since 4 is a perfect square, its square root is 2. -``` - -### Your Task - -You don't need to read input or print anything. The task is to complete the function `floorSqrt()` which takes `x` as the input parameter and returns its square root. Note: Try solving the question without using the sqrt function. The value of `x` ≥ 0. - -**Expected Time Complexity:** $O(log N)$ -**Expected Auxiliary Space:** $O(1)$ - -**Constraints** - -- `1 ≤ x ≤ 10^7` - -## Solution - -### Intuition & Approach - -To find the square root of a number without using the built-in `sqrt` function, we can use binary search. This approach leverages the fact that the square root of `x` must lie between `0` and `x`. By repeatedly narrowing down the range using binary search, we can efficiently find the floor value of the square root. - -### Implementation - - - - -```python -class Solution: - def floorSqrt(self, x: int) -> int: - if x == 0 or x == 1: - return x - start, end = 1, x - ans = 0 - while start <= end: - mid = (start + end) // 2 - if mid * mid == x: - return mid - if mid * mid < x: - start = mid + 1 - ans = mid - else: - end = mid - 1 - return ans -``` - - - - -```java -class Solution { - long floorSqrt(long x) { - if (x == 0 || x == 1) { - return x; - } - long start = 1, end = x, ans = 0; - while (start <= end) { - long mid = (start + end) / 2; - if (mid * mid == x) { - return mid; - } - if (mid * mid < x) { - start = mid + 1; - ans = mid; - } else { - end = mid - 1; - } - } - return ans; - } -} -``` - - - - -```cpp -class Solution { -public: - long long int floorSqrt(long long int x) { - if (x == 0 || x == 1) - return x; - long long int start = 1, end = x, ans = 0; - while (start <= end) { - long long int mid = (start + end) / 2; - if (mid * mid == x) - return mid; - if (mid * mid < x) { - start = mid + 1; - ans = mid; - } else { - end = mid - 1; - } - } - return ans; - } -}; -``` - - - - -```javascript -class Solution { - floorSqrt(x) { - if (x === 0 || x === 1) { - return x; - } - let start = 1, - end = x, - ans = 0; - while (start <= end) { - let mid = Math.floor((start + end) / 2); - if (mid * mid === x) { - return mid; - } - if (mid * mid < x) { - start = mid + 1; - ans = mid; - } else { - end = mid - 1; - } - } - return ans; - } -} -``` - - - - -```typescript -class Solution { - floorSqrt(x: number): number { - if (x === 0 || x === 1) { - return x; - } - let start = 1, - end = x, - ans = 0; - while (start <= end) { - let mid = Math.floor((start + end) / 2); - if (mid * mid === x) { - return mid; - } - if (mid * mid < x) { - start = mid + 1; - ans = mid; - } else { - end = mid - 1; - } - } - return ans; - } -} -``` - - - - -## Complexity Analysis - -The provided solutions efficiently find the floor value of the square root of a given integer `x` using binary search. This approach ensures a time complexity of $ O(log N) and an auxiliary space complexity of $O(1)$. The algorithms are designed to handle large values of `x` up to 10^7 efficiently without relying on built-in square root functions. - -**Time Complexity:** $O(log N)$ -**Auxiliary Space:** $O(1)$ +--- +id: square-root +title: Square Root +sidebar_label: Square-Root +tags: + - Math + - Binary Search +description: "This document provides solutions to the problem of finding the Square Root of an integer." +--- + +## Problem + +Given an integer `x`, find the square root of `x`. If `x` is not a perfect square, then return the floor value of √x. + +### Examples + +**Example 1:** + +``` +Input: x = 5 +Output: 2 +Explanation: Since 5 is not a perfect square, the floor of the square root of 5 is 2. +``` + +**Example 2:** + +``` +Input: x = 4 +Output: 2 +Explanation: Since 4 is a perfect square, its square root is 2. +``` + +### Your Task + +You don't need to read input or print anything. The task is to complete the function `floorSqrt()` which takes `x` as the input parameter and returns its square root. Note: Try solving the question without using the sqrt function. The value of `x` ≥ 0. + +**Expected Time Complexity:** $O(log N)$ +**Expected Auxiliary Space:** $O(1)$ + +**Constraints** + +- `1 ≤ x ≤ 10^7` + +## Solution + +### Intuition & Approach + +To find the square root of a number without using the built-in `sqrt` function, we can use binary search. This approach leverages the fact that the square root of `x` must lie between `0` and `x`. By repeatedly narrowing down the range using binary search, we can efficiently find the floor value of the square root. + +### Implementation + + + + +```python +class Solution: + def floorSqrt(self, x: int) -> int: + if x == 0 or x == 1: + return x + start, end = 1, x + ans = 0 + while start <= end: + mid = (start + end) // 2 + if mid * mid == x: + return mid + if mid * mid < x: + start = mid + 1 + ans = mid + else: + end = mid - 1 + return ans +``` + + + + +```java +class Solution { + long floorSqrt(long x) { + if (x == 0 || x == 1) { + return x; + } + long start = 1, end = x, ans = 0; + while (start <= end) { + long mid = (start + end) / 2; + if (mid * mid == x) { + return mid; + } + if (mid * mid < x) { + start = mid + 1; + ans = mid; + } else { + end = mid - 1; + } + } + return ans; + } +} +``` + + + + +```cpp +class Solution { +public: + long long int floorSqrt(long long int x) { + if (x == 0 || x == 1) + return x; + long long int start = 1, end = x, ans = 0; + while (start <= end) { + long long int mid = (start + end) / 2; + if (mid * mid == x) + return mid; + if (mid * mid < x) { + start = mid + 1; + ans = mid; + } else { + end = mid - 1; + } + } + return ans; + } +}; +``` + + + + +```javascript +class Solution { + floorSqrt(x) { + if (x === 0 || x === 1) { + return x; + } + let start = 1, + end = x, + ans = 0; + while (start <= end) { + let mid = Math.floor((start + end) / 2); + if (mid * mid === x) { + return mid; + } + if (mid * mid < x) { + start = mid + 1; + ans = mid; + } else { + end = mid - 1; + } + } + return ans; + } +} +``` + + + + +```typescript +class Solution { + floorSqrt(x: number): number { + if (x === 0 || x === 1) { + return x; + } + let start = 1, + end = x, + ans = 0; + while (start <= end) { + let mid = Math.floor((start + end) / 2); + if (mid * mid === x) { + return mid; + } + if (mid * mid < x) { + start = mid + 1; + ans = mid; + } else { + end = mid - 1; + } + } + return ans; + } +} +``` + + + + +## Complexity Analysis + +The provided solutions efficiently find the floor value of the square root of a given integer `x` using binary search. This approach ensures a time complexity of $ O(log N) and an auxiliary space complexity of $O(1)$. The algorithms are designed to handle large values of `x` up to 10^7 efficiently without relying on built-in square root functions. + +**Time Complexity:** $O(log N)$ +**Auxiliary Space:** $O(1)$ diff --git a/dsa/Algorithms/Dynamic Programming/15-Z-Algorithm.md b/dsa/Algorithms/Dynamic Programming/15-Z-Algorithm.md new file mode 100644 index 000000000..7fcf60467 --- /dev/null +++ b/dsa/Algorithms/Dynamic Programming/15-Z-Algorithm.md @@ -0,0 +1,172 @@ +--- +id: z-algorithm +title: Z-Algorithm +sidebar_label: Z-Algorithm +tags: [python, java, c++, programming, algorithms, dynamic programming, tutorial, in-depth] +description: In this tutorial, we will learn about the Z-Algorithm and its implementation in Python, Java, and C++ with detailed explanations and examples. +--- + +# Z-Algorithm + +The Z-Algorithm is a linear time algorithm used for pattern matching within a string. It is commonly used to compute the Z-array, which provides information about the occurrences of a substring within a string. The Z-array for a string `S` is an array where the `i-th` position represents the length of the longest substring starting from `S[i]` that matches a prefix of `S`. + +## Problem Statement + +Given a string `S` of length `n`, the Z-array of `S` is an array `Z` of length `n` where `Z[i]` is the length of the longest substring starting from `S[i]` which is also a prefix of `S`. + +## Example + +For the string `S = "aabcaabxaaaz"`, the Z-array would be `[0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0]`. + +## Algorithm + +1. Initialize `L` and `R` to 0. These will define the interval `[L, R]` which is the rightmost segment of `S` that matches the prefix of `S`. +2. Iterate over each character in the string and compute the Z-values based on the interval `[L, R]`. +3. If the current index `i` is outside of `[L, R]`, calculate the Z-value directly. +4. If `i` is within `[L, R]`, use previously computed Z-values to determine the Z-value at `i`. + +## Code for Z-Algorithm + +## Z-Algorithm + +The Z-Algorithm is used for string pattern matching and finding the Z-array, which represents the lengths of the longest substrings starting from each position in a string that match the prefix of the string. + +### Python Implementation + +```python +def compute_z(s): + n = len(s) + z = [0] * n + l, r, k = 0, 0, 0 + for i in range(1, n): + if i > r: + l, r = i, i + while r < n and s[r] == s[r - l]: + r += 1 + z[i] = r - l + r -= 1 + else: + k = i - l + if z[k] < r - i + 1: + z[i] = z[k] + else: + l = i + while r < n and s[r] == s[r - l]: + r += 1 + z[i] = r - l + r -= 1 + return z +s = "aabcaabxaaaz" +print("Z-array:", compute_z(s)) +``` + +### Java Implementation + +```java +public class ZAlgorithm { + public static int[] computeZ(String s) { + int n = s.length(); + int[] z = new int[n]; + int l = 0, r = 0, k; + for (int i = 1; i < n; i++) { + if (i > r) { + l = r = i; + while (r < n && s.charAt(r) == s.charAt(r - l)) { + r++; + } + z[i] = r - l; + r--; + } else { + k = i - l; + if (z[k] < r - i + 1) { + z[i] = z[k]; + } else { + l = i; + while (r < n && s.charAt(r) == s.charAt(r - l)) { + r++; + } + z[i] = r - l; + r--; + } + } + } + return z; + } + + public static void main(String[] args) { + String s = "aabcaabxaaaz"; + int[] z = computeZ(s); + System.out.print("Z-array: "); + for (int value : z) { + System.out.print(value + " "); + } + } +} +``` + +### Cpp Implementation + +```cpp +#include +#include +#include + +using namespace std; + +vector computeZ(const string& s) { + int n = s.length(); + vector z(n, 0); + int l = 0, r = 0, k; + for (int i = 1; i < n; i++) { + if (i > r) { + l = r = i; + while (r < n && s[r] == s[r - l]) { + r++; + } + z[i] = r - l; + r--; + } else { + k = i - l; + if (z[k] < r - i + 1) { + z[i] = z[k]; + } else { + l = i; + while (r < n && s[r] == s[r - l]) { + r++; + } + z[i] = r - l; + r--; + } + } + } + return z; +} + +int main() { + string s = "aabcaabxaaaz"; + vector z = computeZ(s); + cout << "Z-array: "; + for (int value : z) { + cout << value << " "; + } + cout << endl; + return 0; +} +``` + +## Output + +`Z-array: 0 1 0 3 0 1 0 2 0 1 0 0` + + +## Time Complexity + +The Z-Algorithm runs in $O(n)$ time complexity where `n` is the length of the string. This is due to the linear scan of the string and the efficient handling of previously computed Z-values. + +## Space Complexity + +The space complexity is $O(n)$ for storing the Z-array. + +## Conclusion + +The Z-Algorithm is an efficient method for pattern matching and string analysis, providing the Z-array in linear time. This algorithm is widely used in various applications such as substring search and pattern matching.