Skip to content

Leetcode Solution 4 to 10 added #332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
id: Median of Two Sorted Arrays
title: Median of Two Sorted Arrays(Leetcode)
sidebar_label: 0004 - Median of Two Sorted Arrays
tags:
- Array
- Binary Search
- Divide and Conquer
description: Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be $O(log (m+n))$.
---


## Problem Description

| Problem Statement | Solution Link | LeetCode Profile |
| :----------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------- |
| [Median of Two Sorted Arrays on LeetCode](https://leetcode.com/problems/median-of-two-sorted-arrays/description/) | [Median of Two Sorted Arrays Solution on LeetCode](https://leetcode.com/problems/median-of-two-sorted-arrays/editorial/) | [gabaniyash846](https://leetcode.com/u/gabaniyash846/) |

### Problem Statement

Given two sorted arrays `nums1` and `nums2` of size `m` and `n` respectively, return the median of the two sorted arrays.

The overall run time complexity should be $O(log (m+n))$.

**Example 1:**
```
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 2.
```

**Example 2:**
```
Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
```

### Constraints
- `nums1.length == m`
- `nums2.length == n`
- `0 <= m <= 1000`
- `0 <= n <= 1000`
- `1 <= m + n <= 2000`
- `-10^6 <= nums1[i], nums2[i] <= 10^6`

### Solution

#### Approach 1: Merge Sort $(O(m + n))$

**Algorithm:**
1. Merge `nums1` and `nums2` into a single sorted array.
2. Find the median of the merged array:
- If the total number of elements is odd, return the middle element.
- If the total number of elements is even, return the average of the two middle elements.

**Python Implementation:**
```python
def findMedianSortedArrays(nums1, nums2):
merged = []
i = j = 0
while i < len(nums1) and j < len(nums2):
if nums1[i] < nums2[j]:
merged.append(nums1[i])
i += 1
else:
merged.append(nums2[j])
j += 1
merged.extend(nums1[i:])
merged.extend(nums2[j:])

n = len(merged)
if n % 2 == 1:
return merged[n // 2]
else:
return (merged[n // 2 - 1] + merged[n // 2]) / 2.0
```

#### Approach 2: Binary Search $(O(log(min(m, n))))$

**Intuition:**
To achieve $O(log(min(m, n)))$ complexity, use binary search on the smaller array. The goal is to find a partition where the left half of both arrays combined is less than or equal to the right half.

**Algorithm:**
1. Ensure `nums1` is the smaller array.
2. Define `imin` and `imax` for binary search on `nums1`.
3. Calculate `partitionX` and `partitionY` such that:
- `partitionX + partitionY = (m + n + 1) // 2`
4. Check conditions to find the correct partition:
- If `maxLeftX <= minRightY` and `maxLeftY <= minRightX`, you've found the correct partition.
- If `maxLeftX > minRightY`, move `imax` to the left.
- If `maxLeftY > minRightX`, move `imin` to the right.
5. Calculate the median based on the combined lengths of the arrays.

**Python Implementation:**
```python
def findMedianSortedArrays(nums1, nums2):
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1

m, n = len(nums1), len(nums2)
imin, imax, half_len = 0, m, (m + n + 1) // 2

while imin <= imax:
partitionX = (imin + imax) // 2
partitionY = half_len - partitionX

maxLeftX = float('-inf') if partitionX == 0 else nums1[partitionX - 1]
minRightX = float('inf') if partitionX == m else nums1[partitionX]

maxLeftY = float('-inf') if partitionY == 0 else nums2[partitionY - 1]
minRightY = float('inf') if partitionY == n else nums2[partitionY]

if maxLeftX <= minRightY and maxLeftY <= minRightX:
if (m + n) % 2 == 1:
return max(maxLeftX, maxLeftY)
else:
return (max(maxLeftX, maxLeftY) + min(minRightX, minRightY)) / 2.0
elif maxLeftX > minRightY:
imax = partitionX - 1
else:
imin = partitionX + 1
```

### Complexity Analysis

- **Time Complexity:**
- Approach 1:$O(m + n)$ because it involves merging both arrays into one sorted array.
- Approach 2: $O(log(min(m, n)))$ because it performs binary search on the smaller array.

- **Space Complexity:**
- Approach 1: $O(m + n)$ due to the additional space needed for the merged array.
- Approach 2: $O(1)$ because it uses only a constant amount of additional space.

### Summary

Approach 1 is straightforward but not optimal in terms of time complexity for large input sizes. Approach 2 leverages binary search to efficiently find the median with logarithmic time complexity, making it suitable for large arrays.
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
---
id: Longest Palindromic Substring
title: Longest Palindromic Substring(LeetCode)
sidebar_label: 0005-Longest Palindrome Substring
tags:
- String
- Dynamic Programming
description: Given a string s, return the longest palindromic substring in s.
---

## Problem Description

| Problem Statement | Solution Link | LeetCode Profile |
| :-------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------- |
| [Longest Palindromic Substring on LeetCode](https://leetcode.com/problems/longest-palindromic-substring/description/) | [Longest Palindromic Substring Solution on LeetCode](https://leetcode.com/problems/longest-palindromic-substring/editorial/) | [gabaniyash846](https://leetcode.com/u/gabaniyash846/) |

## Problem Statement

Given a string `s`, return the longest palindromic substring in `s`.

### Examples

**Example 1:**
```plaintext
Input: s = "babad"
Output: "bab"
Explanation: "aba" is also a valid answer.
```

**Example 2:**
```plaintext
Input: s = "cbbd"
Output: "bb"
```

### Constraints
- `1 <= s.length <= 1000`
- `s` consist of only digits and English letters.

## Solution

### Approach 1: Check All Substrings

#### Intuition
We can start with a brute-force approach. We will simply check if each substring is a palindrome, and take the longest one that is.

#### Algorithm
1. Create a helper method `check(i, j)` to determine if a substring is a palindrome.
2. Use two pointers to iterate from the start and end of the substring towards the center.
3. If characters at both pointers are equal, move the pointers inward.
4. Use nested loops to check all possible substrings and use the helper method to determine if they are palindromes.
5. Keep track of the longest palindrome found.

#### Implementation
```python
def longestPalindrome(s: str) -> str:
def check(l, r):
while l >= 0 and r < len(s) and s[l] == s[r]:
l -= 1
r += 1
return s[l+1:r]

longest = ""
for i in range(len(s)):
odd_palindrome = check(i, i)
even_palindrome = check(i, i + 1)
longest = max(longest, odd_palindrome, even_palindrome, key=len)

return longest
```

### Complexity Analysis
- **Time complexity**: $O(n^3)$ - We check each substring, and checking each substring takes $O(n)$ time.
- **Space complexity**: $O(1)$ - We use a constant amount of extra space.

### Approach 2: Dynamic Programming

#### Intuition
If we know a substring is a palindrome, we can extend it if the characters on both ends match.

#### Algorithm
1. Initialize a 2D DP table with `False`.
2. Mark all single-character substrings as palindromes.
3. Check substrings of length 2 and mark them if characters match.
4. Use the table to extend palindromes to longer substrings.
5. Keep track of the longest palindrome found.

#### Implementation
```python
def longestPalindrome(s: str) -> str:
n = len(s)
dp = [[False] * n for _ in range(n)]
longest = ""

for i in range(n):
dp[i][i] = True
longest = s[i]

for i in range(n-1):
if s[i] == s[i+1]:
dp[i][i+1] = True
longest = s[i:i+2]

for length in range(3, n+1):
for i in range(n-length+1):
j = i + length - 1
if s[i] == s[j] and dp[i+1][j-1]:
dp[i][j] = True
longest = s[i:j+1]

return longest
```

### Complexity Analysis
- **Time complexity**: $O(n^2)$ - We fill an `n * n` table.
- **Space complexity**: $O(n^2)$ - We use an `n * n` table to store the DP results.

### Approach 3: Expand From Centers

#### Intuition
A palindrome mirrors around its center. We can expand around potential centers to find palindromes.

#### Algorithm
1. Consider each character and pair of characters as potential centers.
2. Expand around each center to find the longest palindrome.
3. Keep track of the longest palindrome found.

#### Implementation
```python
def longestPalindrome(s: str) -> str:
def expandAroundCenter(s, left, right):
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return s[left + 1:right]

if not s:
return ""

longest = s[0]

for i in range(len(s)):
odd_palindrome = expandAroundCenter(s, i, i)
even_palindrome = expandAroundCenter(s, i, i + 1)
longest = max(longest, odd_palindrome, even_palindrome, key=len)

return longest
```

### Complexity Analysis
- **Time complexity**: $O(n^2)$ - We expand around each center, which takes $O(n)$ time.
- **Space complexity**: $O(1)$ - We use a constant amount of extra space.

### Approach 4: Manacher's Algorithm

#### Intuition
Manacher's algorithm can find the longest palindromic substring in linear time.

#### Algorithm
1. Transform the string to handle even-length palindromes.
2. Use a helper array to store the length of the palindrome at each position.
3. Use the properties of palindromes and the helper array to efficiently find the longest palindrome.

#### Implementation
```python
def longestPalindrome(s: str) -> str:
if not s:
return ""

# Transform s into new string with inserted boundaries
T = '#'.join(f"^{s}$")
n = len(T)
P = [0] * n
C = R = 0

for i in range(1, n - 1):
P[i] = (R > i) and min(R - i, P[2 * C - i])
while T[i + P[i] + 1] == T[i - P[i] - 1]:
P[i] += 1
if i + P[i] > R:
C, R = i, i + P[i]

max_len, center_index = max((n, i) for i, n in enumerate(P))
return s[(center_index - max_len) // 2: (center_index + max_len) // 2]
```

### Complexity Analysis
- **Time complexity**: $O(n)$ - Manacher's algorithm runs in linear time.
- **Space complexity**: $O(n)$ - We use an array of length `n` to store the lengths of palindromes.

### Conclusion
We discussed four approaches to solve the "Longest Palindromic Substring" problem, each with varying complexities and trade-offs. The dynamic programming and center expansion approaches provide a good balance of simplicity and efficiency for practical use cases, while Manacher's algorithm offers the optimal theoretical performance.
```

Loading
Loading