Skip to content

Commit d60e6e4

Browse files
committed
add solutions to 300 problems
1 parent 522aed5 commit d60e6e4

File tree

2,100 files changed

+246419
-4850
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,100 files changed

+246419
-4850
lines changed

c#/01-matrix.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# [542. 01 Matrix](https://leetcode.com/problems/01-matrix/)
2+
3+
## Approaches
4+
- [Approach 1: Breadth-First Search (BFS)](#approach-1-bfs)
5+
- [Approach 2: Dynamic Programming](#approach-2-dp)
6+
- [Approach 3: Optimized BFS with a 2-pass solution](#approach-3-optimized-bfs)
7+
8+
### Approach 1: Breadth-First Search (BFS)
9+
10+
**Intuition:**
11+
- The fundamental idea is to find the shortest path from each cell containing `1` to the nearest cell containing `0`.
12+
- We can consider each cell with `0` as the source node and perform a breadth-first search (BFS) to find the shortest distance to all `1`s.
13+
14+
**Steps:**
15+
1. Initialize the result matrix with `int.MaxValue` for each cell.
16+
2. Use a queue to track coordinates of `0` cells and begin BFS from here.
17+
3. For each `0`, attempt to move in all four directions, updating any `1` cell's distance if a shorter path is discovered.
18+
19+
```csharp
20+
public class Solution {
21+
public int[][] UpdateMatrix(int[][] matrix) {
22+
int rows = matrix.Length;
23+
int cols = matrix[0].Length;
24+
int[][] distances = new int[rows][];
25+
Queue<(int, int)> queue = new Queue<(int, int)>();
26+
27+
for (int i = 0; i < rows; i++) {
28+
distances[i] = new int[cols];
29+
for (int j = 0; j < cols; j++) {
30+
// Initialize distances. 0 cells will be the start of BFS.
31+
if (matrix[i][j] == 0) {
32+
queue.Enqueue((i,j));
33+
} else {
34+
distances[i][j] = int.MaxValue;
35+
}
36+
}
37+
}
38+
39+
int[][] directions = new int[][] { new int[] {1, 0}, new int[] {-1, 0}, new int[] {0, 1}, new int[] {0, -1} };
40+
41+
while (queue.Count > 0) {
42+
(int x, int y) = queue.Dequeue();
43+
for (int i = 0; i < directions.Length; i++) {
44+
int newX = x + directions[i][0];
45+
int newY = y + directions[i][1];
46+
// Ensure within bounds and found a shorter path
47+
if (newX >= 0 && newX < rows && newY >= 0 && newY < cols) {
48+
if (distances[newX][newY] > distances[x][y] + 1) {
49+
distances[newX][newY] = distances[x][y] + 1;
50+
queue.Enqueue((newX, newY));
51+
}
52+
}
53+
}
54+
}
55+
return distances;
56+
}
57+
}
58+
```
59+
60+
- **Time Complexity:** O(rows * cols), as each cell is processed at most once.
61+
- **Space Complexity:** O(rows * cols), for the `distances` matrix and queue space.
62+
63+
### Approach 2: Dynamic Programming
64+
65+
**Intuition:**
66+
- We can reduce the problem into finding the minimum distance in two passes: one forward and one backward.
67+
- Update the current cell's distance based on its neighboring cells.
68+
69+
**Steps:**
70+
1. Pass from top-left to bottom-right. For each cell update its distance using the top and left neighbors.
71+
2. Pass from bottom-right to top-left. Update its distance using the bottom and right neighbors.
72+
73+
```csharp
74+
public class Solution {
75+
public int[][] UpdateMatrix(int[][] matrix) {
76+
int rows = matrix.Length;
77+
int cols = matrix[0].Length;
78+
int[][] distances = new int[rows][];
79+
80+
for (int i = 0; i < rows; i++) {
81+
distances[i] = new int[cols];
82+
for (int j = 0; j < cols; j++) {
83+
distances[i][j] = matrix[i][j] == 0 ? 0 : int.MaxValue - 100000; // Avoid overflow in addition
84+
}
85+
}
86+
87+
// Top-left to bottom-right
88+
for (int i = 0; i < rows; i++) {
89+
for (int j = 0; j < cols; j++) {
90+
if (matrix[i][j] != 0) {
91+
if (i > 0) {
92+
distances[i][j] = Math.Min(distances[i][j], distances[i-1][j] + 1);
93+
}
94+
if (j > 0) {
95+
distances[i][j] = Math.Min(distances[i][j], distances[i][j-1] + 1);
96+
}
97+
}
98+
}
99+
}
100+
101+
// Bottom-right to top-left
102+
for (int i = rows - 1; i >= 0; i--) {
103+
for (int j = cols - 1; j >= 0; j--) {
104+
if (i < rows - 1) {
105+
distances[i][j] = Math.Min(distances[i][j], distances[i+1][j] + 1);
106+
}
107+
if (j < cols - 1) {
108+
distances[i][j] = Math.Min(distances[i][j], distances[i][j+1] + 1);
109+
}
110+
}
111+
}
112+
return distances;
113+
}
114+
}
115+
```
116+
117+
- **Time Complexity:** O(rows * cols), two complete passes over the data.
118+
- **Space Complexity:** O(1), as we modify the input matrix directly.
119+
120+
### Approach 3: Optimized BFS with a 2-pass Solution
121+
122+
This uses the first two methods but optimizes BFS by reducing unnecessary checks using a two-pass solution similar to dynamic programming. This method can save some overhead in BFS initialization. Although very similar to the dynamic programming approach, careful attention is paid so initial BFS fills in skews of the grid minimizing the work in the main passes. The same code and logic apply for this optimization.
123+
124+
- **Time Complexity:** O(rows * cols)
125+
- **Space Complexity:** O(rows * cols) for BFS queue usage, reducible to O(1) when done during passes.
126+

c#/132-pattern.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# [Leetcode 456: 132 Pattern](https://leetcode.com/problems/132-pattern/)
2+
3+
## Solutions
4+
5+
- [Brute Force Approach](#brute-force-approach)
6+
- [Optimal Solution Using Stack](#optimal-solution-using-stack)
7+
8+
### Brute Force Approach
9+
10+
#### Intuition
11+
The brute force solution involves checking every possible subsequence of length three for each triplet `(i, j, k)` with conditions `i < j < k` and `nums[i] < nums[k] < nums[j]`. This method essentially checks all combinations of triplets to see if they form the "132" pattern.
12+
13+
#### Approach
14+
1. Use three nested loops to iterate over each possible triplet `(i, j, k)`.
15+
2. For each triplet, check if they satisfy the "132" pattern: `nums[i] < nums[k] < nums[j]`.
16+
3. If we find such a triplet, return `true`.
17+
4. If we finish all iterations without finding such a triplet, return `false`.
18+
19+
#### Complexity
20+
- **Time Complexity**: O(n^3), where n is the length of the input array.
21+
- **Space Complexity**: O(1), as we use only a constant amount of extra space.
22+
23+
```csharp
24+
public bool Find132patternBruteForce(int[] nums)
25+
{
26+
int n = nums.Length;
27+
for (int i = 0; i < n; i++)
28+
{
29+
for (int j = i + 1; j < n; j++)
30+
{
31+
for (int k = j + 1; k < n; k++)
32+
{
33+
// Check for the "132" pattern
34+
if (nums[i] < nums[k] && nums[k] < nums[j])
35+
{
36+
return true;
37+
}
38+
}
39+
}
40+
}
41+
return false;
42+
}
43+
```
44+
45+
### Optimal Solution Using Stack
46+
47+
#### Intuition
48+
This solution involves using a stack to efficiently find the "132" pattern. The idea is to iterate backward through the array and keep track of potential third elements (`nums[k]` in the pattern) using a stack. We maintain a variable to track the potential `nums[k]` as we traverse backwards. If we find a triplet satisfying the 132 conditions, we return true.
49+
50+
#### Approach
51+
1. Initialize a stack to keep potential third elements (`nums[k]`).
52+
2. Start traversing from the end of the array towards the beginning.
53+
3. Keep track of the maximum `nums[k]` found (`third`), initially set to the minimum integer value.
54+
4. For each element `nums[j]`, check if it can potentially be the middle element in the "132" pattern with `third` as `nums[k]`.
55+
5. If `nums[j]` is less than `third`, we've found a valid "132" pattern.
56+
6. If not, push `nums[j]` to the stack, updating `third` if necessary when elements are popped.
57+
7. Continue until a pattern is found or all elements are processed.
58+
59+
#### Complexity
60+
- **Time Complexity**: O(n), as each element is pushed and popped from the stack at most once.
61+
- **Space Complexity**: O(n), due to the stack used to store elements.
62+
63+
```csharp
64+
public bool Find132patternOptimal(int[] nums)
65+
{
66+
int n = nums.Length;
67+
int third = Int32.MinValue;
68+
Stack<int> stack = new Stack<int>();
69+
70+
// Traverse from the end of the list to the beginning
71+
for (int i = n - 1; i >= 0; i--)
72+
{
73+
// If current element is less than the third element of 132 pattern
74+
if (nums[i] < third)
75+
{
76+
return true;
77+
}
78+
79+
// Pop elements from stack until we find something larger than nums[i]
80+
while (stack.Count > 0 && nums[i] > stack.Peek())
81+
{
82+
// Update third
83+
third = stack.Pop();
84+
}
85+
86+
// Push current element onto the stack
87+
stack.Push(nums[i]);
88+
}
89+
return false;
90+
}
91+
```
92+
93+
This solution effectively utilizes a stack to achieve linear time complexity, providing an optimal solution to detect the "132" pattern in an array.
94+

c#/3Sum.md

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,90 @@
1-
# [15. 3Sum](https://leetcode.com/problems/3sum/)
1+
# [3Sum](https://leetcode.com/problems/3sum/)
22

3-
## Approach 1: Brute Force (Basic)
3+
## Approaches:
4+
- [Brute Force Approach](#brute-force-approach)
5+
- [Sorting and Two-Pointer Approach](#sorting-and-two-pointer-approach)
46

5-
### Solution
6-
csharp
7-
```csharp
8-
// Time Complexity: O(n^3)
9-
// Space Complexity: O(1) (excluding output list)
10-
using System;
11-
using System.Collections.Generic;
12-
using System.Linq;
7+
### Brute Force Approach
8+
The brute force approach for solving the 3Sum problem is to generate all possible triplets (i, j, k) where i < j < k. We then check if the sum of the elements at these indices is zero.
9+
10+
**Intuition:**
11+
- Iterate through all unique pairs of indices (i, j, k) in the array, and check if their sum equals zero.
12+
- Since we need combinations without repetitions, ensure i < j < k.
1313

14+
```csharp
1415
public class Solution {
1516
public IList<IList<int>> ThreeSum(int[] nums) {
16-
var result = new HashSet<IList<int>>();
17-
int n = nums.Length;
17+
IList<IList<int>> result = new List<IList<int>>();
1818

19-
// Iterate through all possible triplets
20-
for (int i = 0; i < n - 2; i++) {
21-
for (int j = i + 1; j < n - 1; j++) {
22-
for (int k = j + 1; k < n; k++) {
19+
// Iterate through all elements for the first number
20+
for (int i = 0; i < nums.Length - 2; i++) {
21+
// Iterate for the second number
22+
for (int j = i + 1; j < nums.Length - 1; j++) {
23+
// Iterate for the third number
24+
for (int k = j + 1; k < nums.Length; k++) {
25+
// Check if these three add up to zero
2326
if (nums[i] + nums[j] + nums[k] == 0) {
24-
var triplet = new List<int> { nums[i], nums[j], nums[k] };
25-
triplet.Sort(); // Ensure the triplet is in sorted order
26-
result.Add(triplet); // Add triplet to the set to avoid duplicates
27+
List<int> triplet = new List<int> { nums[i], nums[j], nums[k] };
28+
triplet.Sort(); // Sort to ensure the triplet is in order
29+
if (!ContainsTriplet(result, triplet)) {
30+
result.Add(triplet);
31+
}
2732
}
2833
}
2934
}
3035
}
36+
37+
return result;
38+
}
3139

32-
return result.ToList(); // Convert set to list for the output
40+
private bool ContainsTriplet(IList<IList<int>> list, List<int> triplet) {
41+
foreach (var item in list) {
42+
if (item[0] == triplet[0] && item[1] == triplet[1] && item[2] == triplet[2]) {
43+
return true;
44+
}
45+
}
46+
return false;
3347
}
3448
}
3549
```
3650

37-
## Approach 2: Two Pointers (Optimal)
51+
**Time Complexity:** O(n^3)
52+
**Space Complexity:** O(n), storing the result.
3853

39-
### Solution
40-
csharp
41-
```csharp
42-
// Time Complexity: O(n^2)
43-
// Space Complexity: O(n) (for sorting or output list)
44-
using System;
45-
using System.Collections.Generic;
46-
using System.Linq;
54+
### Sorting and Two-Pointer Approach
55+
This approach reduces the time complexity by first sorting the array and then using a two-pointer strategy to find the pairs that sum to the negative of each element.
4756

57+
**Intuition:**
58+
- Sort the array. This helps in easily skipping duplicates and using a two-pointer method effectively.
59+
- Fix one number a[i] and then find two numbers from the remaining part of the array which sum to -a[i].
60+
- Use two pointers starting from both ends of the remaining array to find the combinations.
61+
62+
```csharp
4863
public class Solution {
4964
public IList<IList<int>> ThreeSum(int[] nums) {
50-
var result = new List<IList<int>>();
51-
Array.Sort(nums); // Sort the array to use two-pointer technique
65+
Array.Sort(nums); // Sort the array
66+
IList<IList<int>> result = new List<IList<int>>();
5267

5368
for (int i = 0; i < nums.Length - 2; i++) {
54-
// Skip duplicates for the first element
55-
if (i > 0 && nums[i] == nums[i - 1]) {
56-
continue;
57-
}
58-
59-
int left = i + 1;
60-
int right = nums.Length - 1;
69+
// Skip duplicates
70+
if (i > 0 && nums[i] == nums[i - 1]) continue;
6171

62-
// Two-pointer approach
72+
int left = i + 1, right = nums.Length - 1;
6373
while (left < right) {
6474
int sum = nums[i] + nums[left] + nums[right];
6575
if (sum == 0) {
6676
result.Add(new List<int> { nums[i], nums[left], nums[right] });
6777

68-
// Skip duplicates for the second and third elements
78+
// Skip duplicates for left and right
6979
while (left < right && nums[left] == nums[left + 1]) left++;
7080
while (left < right && nums[right] == nums[right - 1]) right--;
7181

7282
left++;
7383
right--;
7484
} else if (sum < 0) {
75-
left++; // Increase the sum
85+
left++; // We need a larger sum, move the left pointer to the right
7686
} else {
77-
right--; // Decrease the sum
87+
right--; // We need a smaller sum, move the right pointer to the left
7888
}
7989
}
8090
}
@@ -84,3 +94,6 @@ public class Solution {
8494
}
8595
```
8696

97+
**Time Complexity:** O(n^2)
98+
**Space Complexity:** O(n), storing the result.
99+

0 commit comments

Comments
 (0)