Skip to content

Commit 696aa64

Browse files
authored
Merge branch 'main' into main
2 parents cbd97b8 + 662b3cf commit 696aa64

File tree

9 files changed

+1105
-1
lines changed

9 files changed

+1105
-1
lines changed

dsa-problems/leetcode-problems/0900-0999.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export const problems = [
9999
problemName: "914. X of a Kind in a Deck of Cards",
100100
difficulty: "Easy",
101101
leetCodeLink: "https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards",
102-
solutionLink: "#"
102+
solutionLink: "/dsa-solutions/lc-solutions/0900-0999/x-of-a-kind-in-a-deck-of-cards"
103103
},
104104
{
105105
problemName: "915. Partition Array into Disjoint Intervals",
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
id: permutation-sequence
3+
title: Permutation Sequence(LeetCode)
4+
sidebar_label: 0060-Permutation Sequence
5+
tags:
6+
- Math
7+
- Recursion
8+
description: The set [1, 2, 3, ..., n] contains a total of n! unique permutations. Given n and k, return the kth permutation sequence.
9+
---
10+
11+
## Problem Statement
12+
13+
The set `[1, 2, 3, ..., n]` contains a total of `n!` unique permutations.
14+
15+
By listing and labeling all of the permutations in order, we get the following sequence for `n = 3`:
16+
17+
1. `"123"`
18+
2. `"132"`
19+
3. `"213"`
20+
4. `"231"`
21+
5. `"312"`
22+
6. `"321"`
23+
Given `n` and `k`, return the `kth` permutation sequence.
24+
25+
### Examples
26+
27+
**Example 1:**
28+
29+
```plaintext
30+
Input: n = 3, k = 3
31+
Output: "213"
32+
```
33+
34+
**Example 2:**
35+
36+
```plaintext
37+
Input: n = 4, k = 9
38+
Output: "2314"
39+
```
40+
41+
**Example 3:**
42+
43+
```plaintext
44+
Input: n = 3, k = 1
45+
Output: "123"
46+
```
47+
48+
### Constraints
49+
50+
- `1 <= n <= 9`
51+
- `1 <= k <= n!`
52+
53+
## Solution
54+
55+
### Approach
56+
57+
#### Algorithm
58+
59+
1. Initialize Factorial Values:
60+
* Precompute and store the factorial values of integers from 0 to 9 in a vector `factVal` to get factorials in O(1) time.
61+
2. Initialize Array:
62+
* Create a vector `v` containing elements from 1 to `n`.
63+
3. Recursive Function `setPerm`:
64+
* Base Case: If `n == 1`, append the last remaining element in `v` to `ans` and return.
65+
* Calculate the required index using `k / factVal[n-1]`.
66+
* Handle the corner case where if `k` is a multiple of `(n-1)!`, decrement the index by 1.
67+
* Append the element at the calculated index from `v` to `ans`.
68+
* Remove the selected element from `v`.
69+
* Adjust the value of `k` to be the remainder after dividing by `factVal[n-1]`.
70+
* Make a recursive call with updated values of `n`, `k`, `v`, and `ans`.
71+
4. Construct Result:
72+
* Initialize an empty string `ans`.
73+
* Call the recursive function setPerm with initial values of `v`, `ans`, `n`, `k`, and `factVal`.
74+
* Return the result `ans`.
75+
76+
#### Implementation
77+
78+
```C++
79+
class Solution {
80+
public:
81+
void setPerm(vector<int>& v, string& ans, int n, int k, vector<int>& factVal) {
82+
if (n == 1) {
83+
ans += to_string(v.back());
84+
return;
85+
}
86+
87+
int index = (k / factVal[n-1]);
88+
if (k % factVal[n-1] == 0) {
89+
index--;
90+
}
91+
92+
ans += to_string(v[index]);
93+
v.erase(v.begin() + index);
94+
k -= factVal[n-1] * index;
95+
setPerm(v, ans, n-1, k, factVal);
96+
}
97+
98+
string getPermutation(int n, int k) {
99+
if (n == 1) return "1";
100+
101+
vector<int> factVal = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
102+
string ans = "";
103+
vector<int> v;
104+
for (int i = 1; i <= n; i++) v.emplace_back(i);
105+
106+
setPerm(v, ans, n, k, factVal);
107+
return ans;
108+
}
109+
};
110+
```
111+
112+
### Complexity Analysis
113+
114+
- **Time complexity**: $O(N^2)$
115+
- **Space complexity**: $O(N)$
116+
117+
### Conclusion
118+
119+
This algorithm efficiently finds the k-th permutation of a set of n elements by using a combination of precomputed factorials and recursive selection. The approach ensures that the computation is done in a systematic manner without generating all permutations.
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
---
2+
id: minimum-window-substring
3+
title: Minimum Window Substring(LeetCode)
4+
sidebar_label: 0076-Minimum Window Substring
5+
tags:
6+
- String
7+
- Hash Table
8+
- Sliding Window
9+
description: Given two strings s and t of lengths m and n respectively, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. If there is no such substring, return the empty string "".
10+
---
11+
12+
## Problem Statement
13+
14+
Given two strings `s` and `t` of lengths `m` and `n` respectively, return the minimum window substring of `s` such that every character in `t` (including duplicates) is included in the window. If there is no such substring, return the empty string `""`.
15+
16+
The testcases will be generated such that the answer is unique.
17+
18+
### Examples
19+
20+
**Example 1:**
21+
22+
```plaintext
23+
Input: s = "ADOBECODEBANC", t = "ABC"
24+
Output: "BANC"
25+
Explanation: The minimum window substring "BANC" includes 'A', 'B', and 'C' from string t.
26+
```
27+
28+
**Example 2:**
29+
30+
```plaintext
31+
Input: s = "a", t = "a"
32+
Output: "a"
33+
Explanation: The entire string s is the minimum window.
34+
```
35+
36+
**Example 3:**
37+
38+
```plaintext
39+
Input: s = "a", t = "aa"
40+
Output: ""
41+
Explanation: Both 'a's from t must be included in the window.
42+
Since the largest window of s only has one 'a', return empty string.
43+
```
44+
45+
### Constraints
46+
47+
- `m == s.length`
48+
- `n == t.length`
49+
- `1 <= m, n <= 105`
50+
- `s` and `t` consist of uppercase and lowercase English letters.
51+
52+
## Solution
53+
54+
### Approach 1: C++
55+
56+
#### Algorithm
57+
58+
1. Initialization:
59+
* Create a `map` to count characters in `t`.
60+
* Initialize `counter` to the length of `t`, begin and end pointers to 0, `d` (length of the minimum window) to `INT_MAX`, and `head` to 0.
61+
2. Expand the Window:
62+
* Move the `end` pointer to expand the window.
63+
* Decrease the count in `map` for the current character in `s`.
64+
* If the count in `map` is greater than 0, decrement `counter`.
65+
3. Shrink the Window:
66+
* When `counter` is 0, try to shrink the window by moving the `begin` pointer.
67+
* If the new window size is smaller, update `head` and `d`.
68+
* Increase the count in `map` for the character at `begin`.
69+
* If the count in `map` becomes positive, increment `counter`.
70+
4. Return Result:
71+
* If `d` is still `INT_MAX`, return an empty string.
72+
* Otherwise, return the substring starting from `head` with length `d`.
73+
74+
#### Implementation
75+
76+
```C++
77+
class Solution {
78+
public:
79+
string minWindow(string s, string t) {
80+
vector<int> map(128, 0);
81+
for (char c : t) {
82+
map[c]++;
83+
}
84+
85+
int counter = t.size(), begin = 0, end = 0, d = INT_MAX, head = 0;
86+
while (end < s.size()) {
87+
if (map[s[end++]]-- > 0) {
88+
counter--;
89+
}
90+
while (counter == 0) {
91+
if (end - begin < d) {
92+
head = begin;
93+
d = end - head;
94+
}
95+
if (map[s[begin++]]++ == 0) {
96+
counter++;
97+
}
98+
}
99+
}
100+
return d == INT_MAX ? "" : s.substr(head, d);
101+
}
102+
};
103+
```
104+
105+
### Complexity Analysis
106+
107+
- **Time complexity**: $O(M+N)$
108+
- **Space complexity**: $O(1)$
109+
110+
### Approach 2: Python
111+
112+
#### Algorithm
113+
114+
1. Initialization:
115+
* Create a `needstr` dictionary to count characters in `t`.
116+
* Initialize `needcnt` to the length of `t`, `res` to store the result window, and `start` to 0.
117+
2. Expand the Window:
118+
* Move the `end` pointer to expand the window.
119+
* Decrease the count in `needstr` for the current character in `s`.
120+
* If the count in `needstr` is greater than 0, decrement `needcnt`.
121+
3. Shrink the Window:
122+
* When `needcnt` is 0, try to shrink the window by moving the `start` pointer.
123+
* Adjust the count in `needstr` for the character at `start`.
124+
* If the count in `needstr` becomes positive, increment `needcnt`.
125+
4. Return Result:
126+
* If the result window is valid, return the substring.
127+
* Otherwise, return an empty string.
128+
129+
#### Implementation
130+
131+
```Python
132+
class Solution:
133+
def minWindow(self, s: str, t: str) -> str:
134+
if len(s) < len(t):
135+
return ""
136+
needstr = collections.defaultdict(int)
137+
for ch in t:
138+
needstr[ch] += 1
139+
needcnt = len(t)
140+
res = (0, float('inf'))
141+
start = 0
142+
for end, ch in enumerate(s):
143+
if needstr[ch] > 0:
144+
needcnt -= 1
145+
needstr[ch] -= 1
146+
if needcnt == 0:
147+
while True:
148+
tmp = s[start]
149+
if needstr[tmp] == 0:
150+
break
151+
needstr[tmp] += 1
152+
start += 1
153+
if end - start < res[1] - res[0]:
154+
res = (start, end)
155+
needstr[s[start]] += 1
156+
needcnt += 1
157+
start += 1
158+
return '' if res[1] > len(s) else s[res[0]:res[1]+1]
159+
```
160+
161+
### Complexity Analysis
162+
163+
- **Time complexity**: $O(M+N)$
164+
- **Space complexity**: $O(N)$
165+
166+
### Conclusion
167+
168+
The C++ and Python approaches for finding the minimum window substring are quite similar in their methodology. Both utilize the two-pointer technique, also known as the sliding window approach, to efficiently traverse the string s and dynamically adjust the window to find the smallest valid substring containing all characters of the string t. They maintain a character count map to keep track of the required characters from t and adjust the counts as the window expands and contracts. Additionally, both solutions use a counter variable to monitor the number of characters still needed to form a valid window.

0 commit comments

Comments
 (0)