One Sequence Two Pointers Opposite Direction¶
Table of Contents¶
- 344. Reverse String (Easy)
- 125. Valid Palindrome (Easy)
- 1750. Minimum Length of String After Deleting Similar Ends (Medium)
- 2105. Watering Plants II (Medium)
- 977. Squares of a Sorted Array (Easy)
- 658. Find K Closest Elements (Medium)
- 1471. The k Strongest Values in an Array (Medium)
- 167. Two Sum II - Input Array Is Sorted (Medium)
- 633. Sum of Square Numbers (Medium)
- 2824. Count Pairs Whose Sum is Less than Target (Easy)
- 15. 3Sum (Medium)
- 16. 3Sum Closest (Medium)
- 18. 4Sum (Medium)
- 611. Valid Triangle Number (Medium)
- 1577. Number of Ways Where Square of Number Is Equal to Product of Two Numbers (Medium)
- 923. 3Sum With Multiplicity (Medium)
- 948. Bag of Tokens (Medium)
- 11. Container With Most Water (Medium)
- 42. Trapping Rain Water (Hard)
- 1616. Split Two Strings to Make Palindrome (Medium)
- 1498. Number of Subsequences That Satisfy the Given Sum Condition (Medium)
- 1782. Count Pairs Of Nodes (Hard)
- 1099. Two Sum Less Than K (Easy) 👑
- 360. Sort Transformed Array (Medium) 👑
- 2422. Merge Operations to Turn Array Into a Palindrome (Medium) 👑
- 259. 3Sum Smaller (Medium) 👑
344. Reverse String¶
-
LeetCode | LeetCode CH (Easy)
-
Tags: two pointers, string
from typing import List
def reverseString(s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left, right = 0, len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
s = ["h", "e", "l", "l", "o"]
reverseString(s)
print(s) # ['o', 'l', 'l', 'e', 'h']
125. Valid Palindrome¶
-
LeetCode | LeetCode CH (Easy)
-
Tags: two pointers, string
# List Comprehension
def isPalindrome(s: str) -> bool:
s = [char.lower() for char in s if char.isalnum()]
return s == s[::-1]
# Left Right Pointers
def isPalindromeLR(s: str) -> bool:
left, right = 0, len(s) - 1
while left < right:
while left < right and not s[left].isalnum():
left += 1
while left < right and not s[right].isalnum():
right -= 1
if s[left].lower() != s[right].lower():
return False
left += 1
right -= 1
return True
s = "A man, a plan, a canal: Panama"
print(isPalindrome(s)) # True
print(isPalindromeLR(s)) # True
1750. Minimum Length of String After Deleting Similar Ends¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: two pointers, string
# Sliding Window Variable Size
def minimumLength(s: str) -> int:
left, right = 0, len(s) - 1
while left < right and s[left] == s[right]:
val = s[left]
while left <= right and s[left] == val:
left += 1
while left <= right and s[right] == val:
right -= 1
return right - left + 1
print(minimumLength("cabaabac")) # 0
print(minimumLength("aabccabba")) # 3
2105. Watering Plants II¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, simulation
977. Squares of a Sorted Array¶
-
LeetCode | LeetCode CH (Easy)
-
Tags: array, two pointers, sorting
from typing import List
# Left Right Pointers
def sortedSquares(nums: List[int]) -> List[int]:
"""Returns the squares of the sorted array."""
n = len(nums)
result = [0 for _ in range(n)]
left, right, tail = 0, n - 1, n - 1
while left <= right:
if abs(nums[left]) >= abs(nums[right]):
result[tail] = nums[left] ** 2
left += 1
else:
result[tail] = nums[right] ** 2
right -= 1
tail -= 1
return result
# |---------------------|------|-------|
# | Approach | Time | Space |
# |---------------------|------|-------|
# | Left Right Pointers | O(n) | O(n) |
# |---------------------|------|-------|
nums = [-4, -1, 0, 3, 10]
print(sortedSquares(nums)) # [0, 1, 9, 16, 100]
658. Find K Closest Elements¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, binary search, sliding window, sorting, heap priority queue
1471. The k Strongest Values in an Array¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, sorting
167. Two Sum II - Input Array Is Sorted¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, binary search
from typing import List
# Left Right Pointers
def twoSum(numbers: List[int], target: int) -> List[int]:
left, right = 0, len(numbers) - 1
while left < right:
total = numbers[left] + numbers[right]
if total > target:
right -= 1
elif total < target:
left += 1
else:
return [left + 1, right + 1]
# |------------|------- |---------|
# | Approach | Time | Space |
# |------------|--------|---------|
# | Left Right | O(n) | O(1) |
# |------------|--------|---------|
numbers = [2, 7, 11, 15]
target = 9
print(twoSum(numbers, target)) # [1, 2]
633. Sum of Square Numbers¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: math, two pointers, binary search
2824. Count Pairs Whose Sum is Less than Target¶
-
LeetCode | LeetCode CH (Easy)
-
Tags: array, two pointers, binary search, sorting
15. 3Sum¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, sorting
from typing import List
# Left Right Pointers
def threeSum(nums: List[int]) -> List[List[int]]:
nums.sort()
res = []
n = len(nums)
for i in range(n - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
left, right = i + 1, n - 1
while left < right:
total = nums[i] + nums[left] + nums[right]
if total > 0:
right -= 1
elif total < 0:
left += 1
else:
res.append([nums[i], nums[left], nums[right]])
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
left += 1
right -= 1
return res
nums = [-1, 0, 1, 2, -1, -4]
assert threeSum(nums) == [[-1, -1, 2], [-1, 0, 1]]
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> res;
int n = nums.size();
for (int i = 0; i < n - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1, right = n - 1;
while (left < right) {
int total = nums[i] + nums[left] + nums[right];
if (total > 0)
right--;
else if (total < 0)
left++;
else {
res.push_back({nums[i], nums[left], nums[right]});
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
}
}
}
return res;
}
int main() {
vector<int> nums = {-1, 0, 1, 2, -1, -4};
vector<vector<int>> res = threeSum(nums);
for (auto& v : res) {
for (int i : v) {
cout << i << " ";
}
cout << endl;
}
return 0;
}
16. 3Sum Closest¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, sorting
from typing import List
# Left Right Pointers
def threeSumClosest(nums: List[int], target: int) -> int:
nums.sort()
n = len(nums)
res = 0
minDiff = float("inf")
for i in range(n - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
left, right = i + 1, n - 1
while left < right:
total = nums[i] + nums[left] + nums[right]
if total > target:
if total - target < minDiff:
minDiff = total - target
res = total
right -= 1
elif total < target:
if target - total < minDiff:
minDiff = target - total
res = total
left += 1
else:
return total
return res
nums = [-1, 2, 1, -4]
target = 1
assert threeSumClosest(nums, target) == 2
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int n = nums.size();
int res = 0;
int minDiff = INT_MAX;
for (int i = 0; i < n - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1, right = n - 1;
while (left < right) {
int total = nums[i] + nums[left] + nums[right];
int diff = abs(total - target);
if (diff < minDiff) {
minDiff = diff;
res = total;
}
if (total > target)
right--;
else if (total < target)
left++;
else
return total;
}
}
return res;
}
int main() {
vector<int> nums = {-1, 2, 1, -4};
int target = 1;
cout << threeSumClosest(nums, target) << endl;
return 0;
}
18. 4Sum¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, sorting
from typing import List
# Left Right Pointers
def fourSum(nums: List[int], target: int) -> List[List[int]]:
"""Returns all unique quadruplets that sum up to the target."""
nums.sort()
result = []
for i in range(len(nums) - 3):
if i > 0 and nums[i] == nums[i - 1]:
continue
for j in range(i + 1, len(nums) - 2):
if j > i + 1 and nums[j] == nums[j - 1]:
continue
left = j + 1
right = len(nums) - 1
while left < right:
total = nums[i] + nums[j] + nums[left] + nums[right]
if total > target:
right -= 1
elif total < target:
left += 1
else:
result.append([nums[i], nums[j], nums[left], nums[right]])
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
left += 1
right -= 1
return result
nums = [1, 0, -1, 0, -2, 2]
target = 0
print(fourSum(nums, target))
# [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
611. Valid Triangle Number¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, binary search, greedy, sorting
1577. Number of Ways Where Square of Number Is Equal to Product of Two Numbers¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, hash table, math, two pointers
923. 3Sum With Multiplicity¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, hash table, two pointers, sorting, counting
948. Bag of Tokens¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, greedy, sorting
11. Container With Most Water¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, greedy
- Return the maximum area of water that can be trapped between the vertical lines.
from typing import List
# Brute Force
def maxAreaBF(height: List[int]) -> int:
max_area = 0
for i in range(len(height)):
for j in range(i + 1, len(height)):
h = min(height[i], height[j])
w = j - i
max_area = max(max_area, h * w)
return max_area
# Left Right Pointers
def maxAreaLR(height: List[int]) -> int:
left, right = 0, len(height) - 1
res = 0
while left < right:
h = min(height[left], height[right])
w = right - left
res = max(res, h * w)
if height[left] < height[right]:
left += 1
else:
right -= 1
return res
# |------------|------- |---------|
# | Approach | Time | Space |
# |------------|--------|---------|
# | Brute Force| O(n^2) | O(1) |
# | Left Right | O(n) | O(1) |
# |------------|--------|---------|
height = [1, 8, 6, 2, 5, 4, 8, 3, 7]
print(maxAreaBF(height)) # 49
print(maxAreaLR(height)) # 49
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int maxArea(vector<int>& height) {
int left = 0, right = height.size() - 1;
int res = 0;
while (left < right) {
int h = min(height[left], height[right]);
int w = right - left;
res = max(res, h * w);
if (height[left] < height[right])
left++;
else
right--;
}
return res;
}
int main() {
vector<int> height = {1, 8, 6, 2, 5, 4, 8, 3, 7};
cout << maxArea(height) << endl; // 49
return 0;
}
42. Trapping Rain Water¶
-
LeetCode | LeetCode CH (Hard)
-
Tags: array, two pointers, dynamic programming, stack, monotonic stack
Approach | Time | Space |
---|---|---|
DP | O(N) | O(N) |
Left Right | O(N) | O(1) |
Monotonic | O(N) | O(N) |
from typing import List
# DP
def trapDP(height: List[int]) -> int:
if not height:
return 0
n = len(height)
maxLeft, maxRight = [0 for _ in range(n)], [0 for _ in range(n)]
for i in range(1, n):
maxLeft[i] = max(maxLeft[i - 1], height[i - 1])
for i in range(n - 2, -1, -1):
maxRight[i] = max(maxRight[i + 1], height[i + 1])
res = 0
for i in range(n):
res += max(0, min(maxLeft[i], maxRight[i]) - height[i])
return res
# Left Right Pointers
def trapLR(height: List[int]) -> int:
if not height:
return 0
left, right = 0, len(height) - 1
maxL, maxR = height[left], height[right]
res = 0
while left < right:
if maxL < maxR:
left += 1
maxL = max(maxL, height[left])
res += maxL - height[left]
else:
right -= 1
maxR = max(maxR, height[right])
res += maxR - height[right]
return res
# Monotonic Stack
def trapStack(height: List[int]) -> int:
stack = []
total = 0
for i in range(len(height)):
while stack and height[i] > height[stack[-1]]:
top = stack.pop()
if not stack:
break
distance = i - stack[-1] - 1
bounded_height = min(height[i], height[stack[-1]]) - height[top]
total += distance * bounded_height
stack.append(i)
return total
height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]
print(trapDP(height)) # 6
print(trapLR(height)) # 6
print(trapStack(height)) # 6
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
class Solution
{
public:
int trap(vector<int> &height)
{
if (height.empty())
return 0;
int res = 0;
int left = 0, right = height.size() - 1;
int maxL = height[left], maxR = height[right];
while (left < right)
{
if (maxL < maxR)
{
left++;
maxL = max(maxL, height[left]);
res += maxL - height[left];
}
else
{
right--;
maxR = max(maxR, height[right]);
res += maxR - height[right];
}
}
return res;
}
};
int main()
{
vector<int> height = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
Solution solution;
cout << solution.trap(height) << endl;
return 0;
}
1616. Split Two Strings to Make Palindrome¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: two pointers, string
1498. Number of Subsequences That Satisfy the Given Sum Condition¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, binary search, sorting
1782. Count Pairs Of Nodes¶
-
LeetCode | LeetCode CH (Hard)
-
Tags: array, two pointers, binary search, graph, sorting
1099. Two Sum Less Than K¶
-
LeetCode | LeetCode CH (Easy)
-
Tags: array, two pointers, binary search, sorting
from typing import List
# Left Right Pointers
def twoSumLessThanK(nums: List[int], k: int) -> int:
nums.sort()
left, right = 0, len(nums) - 1
res = float("-inf")
while left < right:
total = nums[left] + nums[right]
if total >= k:
right -= 1
else:
res = max(res, total)
left += 1
return res if res != float("-inf") else -1
nums = [34, 23, 1, 24, 75, 33, 54, 8]
k = 60
print(twoSumLessThanK(nums, k)) # 58
360. Sort Transformed Array¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, math, two pointers, sorting
2422. Merge Operations to Turn Array Into a Palindrome¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, greedy
259. 3Sum Smaller¶
-
LeetCode | LeetCode CH (Medium)
-
Tags: array, two pointers, binary search, sorting