Skip to content

Commit d03d5c7

Browse files
authored
Merge pull request #71 from emseto/csharp-solutions-two-pointers
Added C# solutions for Chapter 1 (Two Pointers)
2 parents 118d17a + 6f86ac8 commit d03d5c7

10 files changed

+322
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
public class Solution
2+
{
3+
public bool IsPalindromeValid(string s)
4+
{
5+
int left = 0, right = s.Length - 1;
6+
while (left < right)
7+
{
8+
// Skip non-alphanumeric characters from the left.
9+
while (left < right && !char.IsLetterOrDigit(s[left]))
10+
{
11+
left++;
12+
}
13+
14+
// Skip non-alphanumeric characters from the right.
15+
while (left < right && !char.IsLetterOrDigit(s[right]))
16+
{
17+
right--;
18+
}
19+
20+
// If the characters at the left and right pointers don't
21+
// match, the string is not a palindrome.
22+
if (s[left] != s[right])
23+
{
24+
return false;
25+
}
26+
27+
left++;
28+
right--;
29+
}
30+
31+
return true;
32+
}
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
public class Solution
2+
{
3+
public int LargestContainer(int[] heights)
4+
{
5+
int max_water = 0;
6+
int left = 0, right = heights.Length - 1;
7+
while (left < right)
8+
{
9+
// Calculate the water contained between the current pair of
10+
// lines.
11+
int water = Math.Min(heights[left], heights[right]) * (right - left);
12+
max_water = Math.Max(max_water, water);
13+
// Move the pointers inward, always moving the pointer at the
14+
// shorter line. If both lines have the same height, move both
15+
// pointers inward.
16+
if (heights[left] < heights[right])
17+
{
18+
left++;
19+
}
20+
else if (heights[left] > heights[right])
21+
{
22+
right--;
23+
}
24+
else
25+
{
26+
left++;
27+
right--;
28+
}
29+
}
30+
31+
return max_water;
32+
}
33+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
public class Solution
2+
{
3+
public int LargestContainerBruteForce(int[] heights)
4+
{
5+
int n = heights.Length;
6+
int max_water = 0;
7+
// Find the maximum amount of water stored between all pairs of
8+
// lines.
9+
for (int i = 0; i < n; i++)
10+
{
11+
for (int j = i + 1; j < n; j++)
12+
{
13+
int water = Math.Min(heights[i], heights[j]) * (j - i);
14+
max_water = Math.Max(max_water, water);
15+
}
16+
}
17+
18+
return max_water;
19+
}
20+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
public class Solution
2+
{
3+
public string NextLexicographicalSequence(string s)
4+
{
5+
char[] letters = s.ToCharArray();
6+
// Locate the pivot, which is the first character from the right that breaks
7+
// non-increasing order. Start searching from the second-to-last position,
8+
// since the last character is neither increasing nor decreasing.
9+
int pivot = letters.Length - 2;
10+
while (pivot >= 0 && letters[pivot] >= letters[pivot + 1])
11+
{
12+
pivot--;
13+
}
14+
// If pivot is not found, the string is already in its largest permutation. In
15+
// this case, reverse the string to obtain the smallest permutation.
16+
if (pivot == -1)
17+
{
18+
ReverseString(letters, 0, letters.Length - 1);
19+
return string.Join("", letters);
20+
}
21+
// Find the rightmost successor to the pivot.
22+
int rightmost_successor = letters.Length - 1;
23+
while (letters[rightmost_successor] <= letters[pivot])
24+
{
25+
rightmost_successor--;
26+
}
27+
// Swap the rightmost successor with the pivot to increase the lexicographical
28+
// order of the suffix.
29+
(letters[pivot], letters[rightmost_successor]) = (letters[rightmost_successor], letters[pivot]);
30+
// Reverse the suffix after the pivot to minimize its permutation.
31+
ReverseString(letters, pivot + 1, letters.Length - 1);
32+
return string.Join("", letters);
33+
}
34+
35+
public void ReverseString(char[] s, int start, int end)
36+
{
37+
while (start < end)
38+
{
39+
(s[start], s[end]) = (s[end], s[start]);
40+
41+
start++;
42+
end--;
43+
}
44+
}
45+
}

csharp/Two Pointers/PairSumSorted.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
public class Solution
2+
{
3+
public int[] PairSumSorted(int[] nums, int target)
4+
{
5+
int left = 0, right = nums.Length - 1;
6+
while (left < right)
7+
{
8+
int sum = nums[left] + nums[right];
9+
// If the sum is smaller, increment the left pointer, aiming
10+
// to increase the sum toward the target value.
11+
if (sum < target)
12+
{
13+
left++;
14+
}
15+
// If the sum is larger, decrement the right pointer, aiming
16+
// to decrease the sum toward the target value.
17+
else if (sum > target)
18+
{
19+
right--;
20+
}
21+
// If the target pair is found, return its indexes.
22+
else
23+
{
24+
return [left, right];
25+
}
26+
}
27+
28+
return [];
29+
}
30+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
public class Solution
2+
{
3+
public int[] PairSumSortedBruteForce(int[] nums, int target)
4+
{
5+
int n = nums.Length;
6+
for (int i = 0; i < n; i++)
7+
{
8+
for (int j = i + 1; j < n; j++)
9+
{
10+
if (nums[i] + nums[j] == target)
11+
{
12+
return [i, j];
13+
}
14+
}
15+
}
16+
17+
return [];
18+
}
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
public class Solution
2+
{
3+
public void ShiftZerosToTheEnd(int[] nums)
4+
{
5+
// The 'left' pointer is used to position non-zero elements.
6+
int left = 0;
7+
// Iterate through the array using a 'right' pointer to locate non-zero
8+
// elements.
9+
for (int right = 0; right < nums.Length; right++)
10+
{
11+
if (nums[right] != 0)
12+
{
13+
(nums[right], nums[left]) = (nums[left], nums[right]);
14+
// Increment 'left' since it now points to a position already occupied
15+
// by a non-zero element.
16+
left++;
17+
}
18+
}
19+
}
20+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
public class Solution
2+
{
3+
public void ShiftZerosToTheEndNaive(int[] nums)
4+
{
5+
int[] temp = new int[nums.Length];
6+
int i = 0;
7+
// Add all non-zero elements to the left of 'temp'.
8+
foreach (int num in nums)
9+
{
10+
if (num != 0)
11+
{
12+
temp[i] = num;
13+
i++;
14+
}
15+
}
16+
17+
// Set 'nums' to 'temp'.
18+
for (int j = 0; j < nums.Length; j++)
19+
{
20+
nums[j] = temp[j];
21+
}
22+
}
23+
}

csharp/Two Pointers/TripletSum.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
public class Solution
2+
{
3+
public IList<IList<int>> TripletSum(int[] nums)
4+
{
5+
IList<IList<int>> triplets = [];
6+
Array.Sort(nums);
7+
for (int i = 0; i < nums.Length; i++)
8+
{
9+
// Optimization: triplets consisting of only positive numbers
10+
// will never sum to 0.
11+
if (nums[i] > 0)
12+
{
13+
break;
14+
}
15+
16+
// To avoid duplicate triplets, skip 'a' if it's the same as
17+
// the previous number.
18+
if (i > 0 && nums[i] == nums[i - 1])
19+
{
20+
continue;
21+
}
22+
23+
// Find all pairs that sum to a target of '-a' (-nums[i]).
24+
IList<IList<int>> pairs = PairSumSortedAllPairs(nums, i + 1, -nums[i]);
25+
foreach (var pair in pairs)
26+
{
27+
triplets.Add([nums[i], pair[0], pair[1]]);
28+
}
29+
}
30+
31+
return triplets;
32+
}
33+
34+
public IList<IList<int>> PairSumSortedAllPairs(int[] nums, int start, int target)
35+
{
36+
IList<IList<int>> pairs = [];
37+
int left = start, right = nums.Length - 1;
38+
while (left < right)
39+
{
40+
int sum = nums[left] + nums[right];
41+
if (sum == target)
42+
{
43+
pairs.Add([nums[left], nums[right]]);
44+
left++;
45+
// To avoid duplicate '[b, c]' pairs, skip 'b' if it's the
46+
// same as the previous number.
47+
while (left < right && nums[left] == nums[left - 1])
48+
{
49+
left++;
50+
}
51+
}
52+
else if (sum < target)
53+
{
54+
left++;
55+
}
56+
else
57+
{
58+
right--;
59+
}
60+
}
61+
62+
return pairs;
63+
}
64+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
public class Solution
2+
{
3+
public IList<IList<int>> TripletSumBruteForce(int[] nums)
4+
{
5+
int n = nums.Length;
6+
// Use a hash set to ensure we don't add duplicate triplets.
7+
HashSet<Tuple<int, int, int>> triplets = [];
8+
// Iterate through the indexes of all triplets.
9+
for (int i = 0; i < n; i++)
10+
{
11+
for (int j = i + 1; j < n; j++)
12+
{
13+
for (int k = j + 1; k < n; k++)
14+
{
15+
if (nums[i] + nums[j] + nums[k] == 0)
16+
{
17+
// Sort the triplet before including it in the
18+
// hash set.
19+
int[] triplet = [nums[i], nums[j], nums[k]];
20+
Array.Sort(triplet);
21+
triplets.Add(new Tuple<int, int, int>(triplet[0], triplet[1], triplet[2]));
22+
}
23+
}
24+
}
25+
}
26+
27+
IList<IList<int>> result = [];
28+
foreach (var triplet in triplets)
29+
{
30+
result.Add([triplet.Item1, triplet.Item2, triplet.Item3]);
31+
}
32+
33+
return result;
34+
}
35+
}

0 commit comments

Comments
 (0)