Skip to content

Commit 3bf3e19

Browse files
committed
Added Golang solutions of 'Two Pointers' tasks
Signed-off-by: Slava Lysunkin <lysunkin@gmail.com>
1 parent d03d5c7 commit 3bf3e19

6 files changed

+172
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
func isAlnum(r rune) bool {
2+
return unicode.IsLetter(r) || unicode.IsDigit(r)
3+
}
4+
5+
func isPalindromeValid(input string) bool {
6+
s := []rune(input)
7+
8+
left, right := 0, len(s)-1
9+
10+
for left < right {
11+
// Skip non-alphanumeric characters from the left.
12+
for left < right && !isAlnum(s[left]) {
13+
left++
14+
}
15+
// Skip non-alphanumeric characters from the right.
16+
for left < right && !isAlnum(s[right]) {
17+
right--
18+
}
19+
// If the characters at the left and right pointers don't
20+
// match, the string is not a palindrome.
21+
if s[left] != s[right] {
22+
return false
23+
}
24+
25+
left++
26+
right--
27+
}
28+
29+
return true
30+
}

go/Two Pointers/largest_container.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
func largestContainer(heights []int) int {
2+
maxWater := 0
3+
left, right := 0, len(heights)-1
4+
5+
for left < right {
6+
// Calculate the water contained between the current pair of
7+
// lines.
8+
water := min(heights[left], heights[right]) * (right - left)
9+
maxWater = max(maxWater, water)
10+
// Move the pointers inward, always moving the pointer at the
11+
// shorter line. If both lines have the same height, move both
12+
// pointers inward.
13+
if heights[left] < heights[right] {
14+
left++
15+
} else if heights[left] > heights[right] {
16+
right--
17+
} else {
18+
left++
19+
right--
20+
}
21+
}
22+
23+
return maxWater
24+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
func reverse(s []rune, start int) {
2+
end := len(s) - 1
3+
for start < end {
4+
s[start], s[end] = s[end], s[start]
5+
start++
6+
end--
7+
}
8+
}
9+
10+
func nextLexicographicalSequence(s string) string {
11+
letters := []rune(s)
12+
// Locate the pivot, which is the first character from the right that breaks
13+
// non-increasing order. Start searching from the second-to-last position.
14+
pivot := len(letters) - 2
15+
for pivot >= 0 && letters[pivot] >= letters[pivot+1] {
16+
pivot--
17+
}
18+
// If pivot is not found, the string is already in its largest permutation. In
19+
// this case, reverse the string to obtain the smallest permutation.
20+
if pivot == -1 {
21+
reverse(letters, 0)
22+
return string(letters)
23+
}
24+
// Find the rightmost successor to the pivot.
25+
rightmostSuccessor := len(letters) - 1
26+
for letters[rightmostSuccessor] <= letters[pivot] {
27+
rightmostSuccessor--
28+
}
29+
// Swap the rightmost successor with the pivot to increase the lexicographical
30+
// order of the suffix.
31+
letters[pivot], letters[rightmostSuccessor] = letters[rightmostSuccessor], letters[pivot]
32+
// Reverse the suffix after the pivot to minimize its permutation.
33+
reverse(letters, pivot+1)
34+
return string(letters)
35+
}

go/Two Pointers/pair_sum_sorted.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
func pairSumSorted(nums []int, target int) []int {
2+
left, right := 0, len(nums)-1
3+
for left < right {
4+
sum := nums[left] + nums[right]
5+
// If the sum is smaller, increment the left pointer, aiming
6+
// to increase the sum toward the target value.
7+
if sum < target {
8+
left++
9+
} else if sum > target {
10+
// If the sum is larger, decrement the right pointer, aiming
11+
// to decrease the sum toward the target value.
12+
right--
13+
} else {
14+
// If the target pair is found, return its indexes.
15+
return []int{left, right}
16+
}
17+
}
18+
return []int{}
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
func shiftZerosToTheEnd(nums []int) {
2+
// The 'left' pointer is used to position non-zero elements.
3+
left := 0
4+
// Iterate through the array using a 'right' pointer to locate non-zero
5+
// elements.
6+
for right := 0; right < len(nums); right++ {
7+
if nums[right] != 0 {
8+
nums[left], nums[right] = nums[right], nums[left]
9+
// Increment 'left' since it now points to a position already occupied
10+
// by a non-zero element.
11+
left++
12+
}
13+
}
14+
}

go/Two Pointers/triplet_sum.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
func tripletSum(nums []int) [][]int {
2+
triplets := [][]int{}
3+
sort.Ints(nums)
4+
5+
for i := 0; i < len(nums); i++ {
6+
// Optimization: triplets consisting of only positive numbers
7+
// will never sum to 0.
8+
9+
if nums[i] > 0 {
10+
break
11+
}
12+
13+
// To avoid duplicate triplets, skip 'a' if it's the same as
14+
// the previous number.
15+
if i > 0 && nums[i] == nums[i-1] {
16+
continue
17+
}
18+
19+
// Find all pairs that sum to a target of '-a' (-nums[i]).
20+
pairs := pairSumSortedAllPairs(nums, i+1, -nums[i])
21+
for _, pair := range pairs {
22+
triplets = append(triplets, []int{nums[i], pair[0], pair[1]})
23+
}
24+
}
25+
26+
return triplets
27+
}
28+
29+
func pairSumSortedAllPairs(nums []int, start int, target int) [][]int {
30+
pairs := [][]int{}
31+
left, right := start, len(nums)-1
32+
for left < right {
33+
sum := nums[left] + nums[right]
34+
if sum == target {
35+
pairs = append(pairs, []int{nums[left], nums[right]})
36+
left++
37+
// To avoid duplicate '[b, c]' pairs, skip 'b' if it's the
38+
// same as the previous number.
39+
for left < right && nums[left] == nums[left-1] {
40+
left++
41+
}
42+
} else if sum < target {
43+
left++
44+
} else {
45+
right--
46+
}
47+
}
48+
49+
return pairs
50+
}

0 commit comments

Comments
 (0)