Skip to content

Commit 5feba01

Browse files
authored
Merge pull request #75 from lysunkin/GO_TWO_POINTERS
Added Golang solutions of 'Two Pointers' tasks
2 parents d15a503 + 1496a67 commit 5feba01

6 files changed

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

go/Two Pointers/largest_container.go

+24
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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
func nextLexicographicalSequence(s string) string {
2+
letters := []rune(s)
3+
// Locate the pivot, which is the first character from the right that breaks
4+
// non-increasing order. Start searching from the second-to-last position.
5+
pivot := len(letters) - 2
6+
for pivot >= 0 && letters[pivot] >= letters[pivot+1] {
7+
pivot--
8+
}
9+
// If pivot is not found, the string is already in its largest permutation. In
10+
// this case, reverse the string to obtain the smallest permutation.
11+
if pivot == -1 {
12+
reverse(letters, 0)
13+
return string(letters)
14+
}
15+
// Find the rightmost successor to the pivot.
16+
rightmostSuccessor := len(letters) - 1
17+
for letters[rightmostSuccessor] <= letters[pivot] {
18+
rightmostSuccessor--
19+
}
20+
// Swap the rightmost successor with the pivot to increase the lexicographical
21+
// order of the suffix.
22+
letters[pivot], letters[rightmostSuccessor] = letters[rightmostSuccessor], letters[pivot]
23+
// Reverse the suffix after the pivot to minimize its permutation.
24+
reverse(letters, pivot+1)
25+
return string(letters)
26+
}
27+
28+
func reverse(s []rune, start int) {
29+
end := len(s) - 1
30+
for start < end {
31+
s[start], s[end] = s[end], s[start]
32+
start++
33+
end--
34+
}
35+
}

go/Two Pointers/pair_sum_sorted.go

+19
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 nil
19+
}
+14
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

+50
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)