Skip to content

Commit d37dcf9

Browse files
authored
Merge pull request #332 from Yashgabani845/main
Leetcode Solution 4 to 10 added
2 parents b5a4040 + 81a036d commit d37dcf9

7 files changed

+1349
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
id: Median of Two Sorted Arrays
3+
title: Median of Two Sorted Arrays(Leetcode)
4+
sidebar_label: 0004 - Median of Two Sorted Arrays
5+
tags:
6+
- Array
7+
- Binary Search
8+
- Divide and Conquer
9+
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))$.
10+
---
11+
12+
13+
## Problem Description
14+
15+
| Problem Statement | Solution Link | LeetCode Profile |
16+
| :----------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------- |
17+
| [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/) |
18+
19+
### Problem Statement
20+
21+
Given two sorted arrays `nums1` and `nums2` of size `m` and `n` respectively, return the median of the two sorted arrays.
22+
23+
The overall run time complexity should be $O(log (m+n))$.
24+
25+
**Example 1:**
26+
```
27+
Input: nums1 = [1,3], nums2 = [2]
28+
Output: 2.00000
29+
Explanation: merged array = [1,2,3] and median is 2.
30+
```
31+
32+
**Example 2:**
33+
```
34+
Input: nums1 = [1,2], nums2 = [3,4]
35+
Output: 2.50000
36+
Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
37+
```
38+
39+
### Constraints
40+
- `nums1.length == m`
41+
- `nums2.length == n`
42+
- `0 <= m <= 1000`
43+
- `0 <= n <= 1000`
44+
- `1 <= m + n <= 2000`
45+
- `-10^6 <= nums1[i], nums2[i] <= 10^6`
46+
47+
### Solution
48+
49+
#### Approach 1: Merge Sort $(O(m + n))$
50+
51+
**Algorithm:**
52+
1. Merge `nums1` and `nums2` into a single sorted array.
53+
2. Find the median of the merged array:
54+
- If the total number of elements is odd, return the middle element.
55+
- If the total number of elements is even, return the average of the two middle elements.
56+
57+
**Python Implementation:**
58+
```python
59+
def findMedianSortedArrays(nums1, nums2):
60+
merged = []
61+
i = j = 0
62+
while i < len(nums1) and j < len(nums2):
63+
if nums1[i] < nums2[j]:
64+
merged.append(nums1[i])
65+
i += 1
66+
else:
67+
merged.append(nums2[j])
68+
j += 1
69+
merged.extend(nums1[i:])
70+
merged.extend(nums2[j:])
71+
72+
n = len(merged)
73+
if n % 2 == 1:
74+
return merged[n // 2]
75+
else:
76+
return (merged[n // 2 - 1] + merged[n // 2]) / 2.0
77+
```
78+
79+
#### Approach 2: Binary Search $(O(log(min(m, n))))$
80+
81+
**Intuition:**
82+
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.
83+
84+
**Algorithm:**
85+
1. Ensure `nums1` is the smaller array.
86+
2. Define `imin` and `imax` for binary search on `nums1`.
87+
3. Calculate `partitionX` and `partitionY` such that:
88+
- `partitionX + partitionY = (m + n + 1) // 2`
89+
4. Check conditions to find the correct partition:
90+
- If `maxLeftX <= minRightY` and `maxLeftY <= minRightX`, you've found the correct partition.
91+
- If `maxLeftX > minRightY`, move `imax` to the left.
92+
- If `maxLeftY > minRightX`, move `imin` to the right.
93+
5. Calculate the median based on the combined lengths of the arrays.
94+
95+
**Python Implementation:**
96+
```python
97+
def findMedianSortedArrays(nums1, nums2):
98+
if len(nums1) > len(nums2):
99+
nums1, nums2 = nums2, nums1
100+
101+
m, n = len(nums1), len(nums2)
102+
imin, imax, half_len = 0, m, (m + n + 1) // 2
103+
104+
while imin <= imax:
105+
partitionX = (imin + imax) // 2
106+
partitionY = half_len - partitionX
107+
108+
maxLeftX = float('-inf') if partitionX == 0 else nums1[partitionX - 1]
109+
minRightX = float('inf') if partitionX == m else nums1[partitionX]
110+
111+
maxLeftY = float('-inf') if partitionY == 0 else nums2[partitionY - 1]
112+
minRightY = float('inf') if partitionY == n else nums2[partitionY]
113+
114+
if maxLeftX <= minRightY and maxLeftY <= minRightX:
115+
if (m + n) % 2 == 1:
116+
return max(maxLeftX, maxLeftY)
117+
else:
118+
return (max(maxLeftX, maxLeftY) + min(minRightX, minRightY)) / 2.0
119+
elif maxLeftX > minRightY:
120+
imax = partitionX - 1
121+
else:
122+
imin = partitionX + 1
123+
```
124+
125+
### Complexity Analysis
126+
127+
- **Time Complexity:**
128+
- Approach 1:$O(m + n)$ because it involves merging both arrays into one sorted array.
129+
- Approach 2: $O(log(min(m, n)))$ because it performs binary search on the smaller array.
130+
131+
- **Space Complexity:**
132+
- Approach 1: $O(m + n)$ due to the additional space needed for the merged array.
133+
- Approach 2: $O(1)$ because it uses only a constant amount of additional space.
134+
135+
### Summary
136+
137+
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.
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
---
2+
id: Longest Palindromic Substring
3+
title: Longest Palindromic Substring(LeetCode)
4+
sidebar_label: 0005-Longest Palindrome Substring
5+
tags:
6+
- String
7+
- Dynamic Programming
8+
description: Given a string s, return the longest palindromic substring in s.
9+
---
10+
11+
## Problem Description
12+
13+
| Problem Statement | Solution Link | LeetCode Profile |
14+
| :-------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------- |
15+
| [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/) |
16+
17+
## Problem Statement
18+
19+
Given a string `s`, return the longest palindromic substring in `s`.
20+
21+
### Examples
22+
23+
**Example 1:**
24+
```plaintext
25+
Input: s = "babad"
26+
Output: "bab"
27+
Explanation: "aba" is also a valid answer.
28+
```
29+
30+
**Example 2:**
31+
```plaintext
32+
Input: s = "cbbd"
33+
Output: "bb"
34+
```
35+
36+
### Constraints
37+
- `1 <= s.length <= 1000`
38+
- `s` consist of only digits and English letters.
39+
40+
## Solution
41+
42+
### Approach 1: Check All Substrings
43+
44+
#### Intuition
45+
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.
46+
47+
#### Algorithm
48+
1. Create a helper method `check(i, j)` to determine if a substring is a palindrome.
49+
2. Use two pointers to iterate from the start and end of the substring towards the center.
50+
3. If characters at both pointers are equal, move the pointers inward.
51+
4. Use nested loops to check all possible substrings and use the helper method to determine if they are palindromes.
52+
5. Keep track of the longest palindrome found.
53+
54+
#### Implementation
55+
```python
56+
def longestPalindrome(s: str) -> str:
57+
def check(l, r):
58+
while l >= 0 and r < len(s) and s[l] == s[r]:
59+
l -= 1
60+
r += 1
61+
return s[l+1:r]
62+
63+
longest = ""
64+
for i in range(len(s)):
65+
odd_palindrome = check(i, i)
66+
even_palindrome = check(i, i + 1)
67+
longest = max(longest, odd_palindrome, even_palindrome, key=len)
68+
69+
return longest
70+
```
71+
72+
### Complexity Analysis
73+
- **Time complexity**: $O(n^3)$ - We check each substring, and checking each substring takes $O(n)$ time.
74+
- **Space complexity**: $O(1)$ - We use a constant amount of extra space.
75+
76+
### Approach 2: Dynamic Programming
77+
78+
#### Intuition
79+
If we know a substring is a palindrome, we can extend it if the characters on both ends match.
80+
81+
#### Algorithm
82+
1. Initialize a 2D DP table with `False`.
83+
2. Mark all single-character substrings as palindromes.
84+
3. Check substrings of length 2 and mark them if characters match.
85+
4. Use the table to extend palindromes to longer substrings.
86+
5. Keep track of the longest palindrome found.
87+
88+
#### Implementation
89+
```python
90+
def longestPalindrome(s: str) -> str:
91+
n = len(s)
92+
dp = [[False] * n for _ in range(n)]
93+
longest = ""
94+
95+
for i in range(n):
96+
dp[i][i] = True
97+
longest = s[i]
98+
99+
for i in range(n-1):
100+
if s[i] == s[i+1]:
101+
dp[i][i+1] = True
102+
longest = s[i:i+2]
103+
104+
for length in range(3, n+1):
105+
for i in range(n-length+1):
106+
j = i + length - 1
107+
if s[i] == s[j] and dp[i+1][j-1]:
108+
dp[i][j] = True
109+
longest = s[i:j+1]
110+
111+
return longest
112+
```
113+
114+
### Complexity Analysis
115+
- **Time complexity**: $O(n^2)$ - We fill an `n * n` table.
116+
- **Space complexity**: $O(n^2)$ - We use an `n * n` table to store the DP results.
117+
118+
### Approach 3: Expand From Centers
119+
120+
#### Intuition
121+
A palindrome mirrors around its center. We can expand around potential centers to find palindromes.
122+
123+
#### Algorithm
124+
1. Consider each character and pair of characters as potential centers.
125+
2. Expand around each center to find the longest palindrome.
126+
3. Keep track of the longest palindrome found.
127+
128+
#### Implementation
129+
```python
130+
def longestPalindrome(s: str) -> str:
131+
def expandAroundCenter(s, left, right):
132+
while left >= 0 and right < len(s) and s[left] == s[right]:
133+
left -= 1
134+
right += 1
135+
return s[left + 1:right]
136+
137+
if not s:
138+
return ""
139+
140+
longest = s[0]
141+
142+
for i in range(len(s)):
143+
odd_palindrome = expandAroundCenter(s, i, i)
144+
even_palindrome = expandAroundCenter(s, i, i + 1)
145+
longest = max(longest, odd_palindrome, even_palindrome, key=len)
146+
147+
return longest
148+
```
149+
150+
### Complexity Analysis
151+
- **Time complexity**: $O(n^2)$ - We expand around each center, which takes $O(n)$ time.
152+
- **Space complexity**: $O(1)$ - We use a constant amount of extra space.
153+
154+
### Approach 4: Manacher's Algorithm
155+
156+
#### Intuition
157+
Manacher's algorithm can find the longest palindromic substring in linear time.
158+
159+
#### Algorithm
160+
1. Transform the string to handle even-length palindromes.
161+
2. Use a helper array to store the length of the palindrome at each position.
162+
3. Use the properties of palindromes and the helper array to efficiently find the longest palindrome.
163+
164+
#### Implementation
165+
```python
166+
def longestPalindrome(s: str) -> str:
167+
if not s:
168+
return ""
169+
170+
# Transform s into new string with inserted boundaries
171+
T = '#'.join(f"^{s}$")
172+
n = len(T)
173+
P = [0] * n
174+
C = R = 0
175+
176+
for i in range(1, n - 1):
177+
P[i] = (R > i) and min(R - i, P[2 * C - i])
178+
while T[i + P[i] + 1] == T[i - P[i] - 1]:
179+
P[i] += 1
180+
if i + P[i] > R:
181+
C, R = i, i + P[i]
182+
183+
max_len, center_index = max((n, i) for i, n in enumerate(P))
184+
return s[(center_index - max_len) // 2: (center_index + max_len) // 2]
185+
```
186+
187+
### Complexity Analysis
188+
- **Time complexity**: $O(n)$ - Manacher's algorithm runs in linear time.
189+
- **Space complexity**: $O(n)$ - We use an array of length `n` to store the lengths of palindromes.
190+
191+
### Conclusion
192+
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.
193+
```
194+

0 commit comments

Comments
 (0)