Two Pointers Flashcards

1
Q
  1. Valid Palindrome
    Solved
    Easy
    Topics
    Companies
    A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.

Given a string s, return true if it is a palindrome, or false otherwise.

Example 1:

Input: s = “A man, a plan, a canal: Panama”
Output: true
Explanation: “amanaplanacanalpanama” is a palindrome.
Example 2:

Input: s = “race a car”
Output: false
Explanation: “raceacar” is not a palindrome.
Example 3:

Input: s = “ “
Output: true
Explanation: s is an empty string “” after removing non-alphanumeric characters.
Since an empty string reads the same forward and backward, it is a palindrome.

Constraints:

1 <= s.length <= 2 * 105
s consists only of printable ASCII characters.

https://leetcode.com/problems/valid-palindrome/

A

class Solution(object):
def isPalindrome(self, s):
“””
:type s: str
:rtype: bool
“””
i, j = 0, len(s) - 1
while(i < j):
while(i < j and not s[i].isalnum()):
i+=1
while(i < j and not s[j].isalnum()):
j-=1
if(s[i].lower() != s[j].lower()):
return False
i+=1
j-=1
return True

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q
  1. Two Sum II - Input Array Is Sorted
    Solved
    Medium
    Topics
    Companies
    Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number. Let these two numbers be numbers[index1] and numbers[index2] where 1 <= index1 < index2 <= numbers.length.

Return the indices of the two numbers, index1 and index2, added by one as an integer array [index1, index2] of length 2.

The tests are generated such that there is exactly one solution. You may not use the same element twice.

Your solution must use only constant extra space.

Example 1:

Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore, index1 = 1, index2 = 2. We return [1, 2].
Example 2:

Input: numbers = [2,3,4], target = 6
Output: [1,3]
Explanation: The sum of 2 and 4 is 6. Therefore index1 = 1, index2 = 3. We return [1, 3].
Example 3:

Input: numbers = [-1,0], target = -1
Output: [1,2]
Explanation: The sum of -1 and 0 is -1. Therefore index1 = 1, index2 = 2. We return [1, 2].

Constraints:

2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers is sorted in non-decreasing order.
-1000 <= target <= 1000
The tests are generated such that there is exactly one solution.

https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/

A

can use hashmap also but it wont use the sorted property to give o1 space

class Solution(object):
def twoSum(self, numbers, target):
“””
:type numbers: List[int]
:type target: int
:rtype: List[int]
“””
l = 0
r = len(numbers) - 1
while l < r:
s = numbers[l] + numbers[r]
if s > target:
r -= 1
elif s < target:
l += 1
else:
return [l+1, r+1]

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q
  1. 3Sum
    Medium
    Companies: Many
    Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

Example 1:

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Explanation:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.
The distinct triplets are [-1,0,1] and [-1,-1,2].
Notice that the order of the output and the order of the triplets does not matter.
Example 2:

Input: nums = [0,1,1]
Output: []
Explanation: The only possible triplet does not sum up to 0.
Example 3:

Input: nums = [0,0,0]
Output: [[0,0,0]]
Explanation: The only possible triplet sums up to 0.

Constraints:

3 <= nums.length <= 3000
-105 <= nums[i] <= 105

https://leetcode.com/problems/3sum/

A

look at code to see how we are removing duplicates. we sort the array and then move pointer till we reach a different element. for both 2sum and 3sum methods. this is important.

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        sortnum = sorted(nums)
        i = 0
        out = []
        while i < len(sortnum) - 2:
            if sortnum[i] > 0:
                break
            if i > 0 and sortnum[i] == sortnum[i-1]:
                i+=1
            else:
                out = out + (self.twoSum(sortnum[i+1:], -sortnum[i]))
                i+=1
        return out
        

        

    def twoSum(self, nums, target):
        l = 0
        r = len(nums) - 1
        out = []
        while l < r:
            s = nums[l] + nums[r]
            if s < target:
                l+=1
            elif s > target:
                r-=1
            else:
                out.append([-1 * target, nums[l], nums[r]])
                l+=1
                r-=1
            if l > 0 and nums[l] == nums[l-1]:
                while l < r and nums[l] == nums[l-1]:
                    l+=1
        return out
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q
  1. Container With Most Water
    Medium
    Companies: Google and many similar.

You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]).

Find two lines that together with the x-axis form a container, such that the container contains the most water.

Return the maximum amount of water a container can store.

Notice that you may not slant the container.

Example 1:

Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49
Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
Example 2:

Input: height = [1,1]
Output: 1

Constraints:

n == height.length
2 <= n <= 105
0 <= height[i] <= 104

https://leetcode.com/problems/container-with-most-water/

A

start at ends , keep track of max height indices for both left and right pointers

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        r = len(height) - 1
        lmax = 0
        rmax = r
        l = 0
        maxarea = 0
        while l < r:
            if height[l] > height[lmax]:
                lmax = l
            if height[r] > height[rmax]:
                rmax = r
            maxarea = max(maxarea, min(height[lmax], height[rmax]) * (rmax - lmax))
            if height[lmax] > height[rmax]:
                r-=1
            elif height[rmax] > height[lmax]:
                l+=1
            else:
                l+=1
                r-=1
        return maxarea

concise way
~~~
class Solution:
def maxArea(self, height: List[int]) -> int:
l = 0
r = len(height) - 1
ret = 0
while(l < r):
area = (r - l) * min(height[l], height[r])
ret = max(ret,area)
if height[l] < height[r]:
l+=1
else:
r-=1
return ret
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q
  1. Trapping Rain Water
    Solved
    Hard
    Topics
    Companies
    Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.

Example 1:

Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.
Example 2:

Input: height = [4,2,0,3,2,5]
Output: 9

Constraints:

n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105

https://leetcode.com/problems/trapping-rain-water/

A

trick is to calculate tallest wall for left and right and then calculate how much water can you store at each index given the wall sizes.

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        l = 0
        r = len(height) - 1 
        maxL = height[l]
        maxR = height[r]
        water = 0
        while l < r:
            if maxL < maxR:
                l+=1
                maxL = max(maxL, height[l])
                water += (maxL - height[l])
            else:
                r-=1
                maxR = max(maxR, height[r])
                water += (maxR - height[r])
        return water
class Solution:
    def trap(self, height: List[int]) -> int:
        n = len(height)
        lmax = 0
        l = 0
        rmax = n-1
        r = n-1
        ret = 0
        ws = [0] * n
        while l < r:
            if height[l] > height[lmax]:
                lmax = l
            if height[r] > height[rmax]:
                rmax = r
            minwall = min(height[lmax], height[rmax])
            ws[l] = max(0, minwall - height[l])
            ws[r] = max(0, minwall - height[r])
            if height[l] < height[r]:
                l+=1
            else:
                r-=1
        return sum(ws)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q
  1. Length of the Longest Valid Substring
    Solved
    Hard

Topics

Companies Amazon
You are given a string word and an array of strings forbidden.

A string is called valid if none of its substrings are present in forbidden.

Return the length of the longest valid substring of the string word.

A substring is a contiguous sequence of characters in a string, possibly empty.

Example 1:

Input: word = “cbaaaabc”, forbidden = [“aaa”,”cb”]
Output: 4
Explanation: There are 11 valid substrings in word: “c”, “b”, “a”, “ba”, “aa”, “bc”, “baa”, “aab”, “ab”, “abc” and “aabc”. The length of the longest valid substring is 4.
It can be shown that all other substrings contain either “aaa” or “cb” as a substring.
Example 2:

Input: word = “leetcode”, forbidden = [“de”,”le”,”e”]
Output: 4
Explanation: There are 11 valid substrings in word: “l”, “t”, “c”, “o”, “d”, “tc”, “co”, “od”, “tco”, “cod”, and “tcod”. The length of the longest valid substring is 4.
It can be shown that all other substrings contain either “de”, “le”, or “e” as a substring.

Constraints:

1 <= word.length <= 105
word consists only of lowercase English letters.
1 <= forbidden.length <= 105
1 <= forbidden[i].length <= 10
forbidden[i] consists only of lowercase English letters.

https://leetcode.com/problems/length-of-the-longest-valid-substring/description/

A
class Solution:
    def longestValidSubstring(self, word: str, forbidden: List[str]) -> int:
        f = set(forbidden)
        mlen = 0
        ret = 0
        for fb in forbidden:
            mlen = max(mlen, len(fb))
        r = len(word)
        for l in range(len(word)-1, -1, -1):
            if r <= ret:
                break
            for j in range(l, min(r, l+mlen)):
                if word[l:j+1] in f:
                    r = j
                    break
            ret = max(ret, r - l)
        return ret
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q
  1. Valid Palindrome II

Companies: facebook 2024

Given a string s, return true if the s can be palindrome after deleting at most one character from it.

Example 1:

Input: s = “aba”
Output: true

Example 2:

Input: s = “abca”
Output: true
Explanation: You could delete the character ‘c’.

Example 3:

Input: s = “abc”
Output: false

Constraints:

1 <= s.length <= 105
s consists of lowercase English letters.

O(n), O(n) Follow up: do it in O(1) space

https://leetcode.com/problems/valid-palindrome-ii/description/

A

If char l and r are not equal, remove l and check if its palindrome or remove r and check if its palindrome

class Solution:
    def validPalindrome(self, s: str) -> bool:
        p = 1
        l = 0
        r = len(s)-1
        while l < r:
            if s[l] != s[r]:
                s1 = s[:l] + s[l+1:]
                s2 = s[:r] + s[r+1:]
                return s1[::-1] == s1 or s2[::-1] == s2
            else:
                l += 1
                r -= 1
        return True

Backtracking

def validPalindrome(self, s: str) -> bool:
    def verify(s, left, right, deleted):
        while left < right:
            if s[left] != s[right]:
                if deleted:
                    return False
                else:
                    return verify(s, left+1, right, True) or verify(s, left, right-1, True)
            else:
                left += 1
                right -= 1
        return True
    return verify(s, 0, len(s)-1, False)

O(1) solution
~~~
class Solution(object):
def validPalindrome(self, s):
“””
:type s: str
:rtype: bool
“””
i, j = 0, len(s)-1
check_a, check_b = True, True
while i < j:
if s[i] != s[j]:
ib, jb = i,j
while(i+1<j):
if s[i+1] != s[j]:
check_a = False
break
i+=1
j-=1
while(ib < jb-1):
if s[ib] != s[jb-1]:
check_b = False
ib+=1
jb-=1
return check_a or check_b
else:
i+=1
j-=1
return True
~~~

10 Minutes target

O(n), O(n) Because we store s1 and s2

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q
  1. Palindromic Substrings
    Solved
    Medium
    Topics
    Companies
    Hint

Given a string s, return the number of palindromic substrings in it.

A string is a palindrome when it reads the same backward as forward.

A substring is a contiguous sequence of characters within the string.

Example 1:

Input: s = “abc”
Output: 3
Explanation: Three palindromic strings: “a”, “b”, “c”.

Example 2:

Input: s = “aaa”
Output: 6
Explanation: Six palindromic strings: “a”, “a”, “a”, “aa”, “aa”, “aaa”.

Constraints:

1 <= s.length <= 1000
s consists of lowercase English letters.

O(n^2), O(n) Space - O(1) if you can.

https://leetcode.com/problems/palindromic-substrings/description/

A

Expand from center approach: if s[i:j+1] is palindrome we can keep expanding window till we fail this check.
~~~
class Solution(object):
def countSubstrings(self, s):
“””
:type s: str
:rtype: int
“””
n = len(s)
palins = 0

    def palin(i,j):
        palins = 0
        while (i >= 0 and j <= len(s) - 1) and s[i] == s[j]:
            i -= 1
            j += 1
            palins += 1
        return palins
    
    for start in range(n):
        # odd
        odd = palin(start, start)
        palins += odd
        even = palin(start, start+1)
        palins += even
    return palins ~~~
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q
  1. Longest Palindromic Substring
    Medium
    Companies: Multiple in 2024

Given a string s, return the longest
palindromic
substring
in s.

Example 1:

Input: s = “babad”
Output: “bab”
Explanation: “aba” is also a valid answer.

Example 2:

Input: s = “cbbd”
Output: “bb”

Constraints:

1 <= s.length <= 1000
s consist of only digits and English letters.

O(n^2), O(n)/O(1) space

https://leetcode.com/problems/longest-palindromic-substring/description/

A
class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        mlen = 1
        mi,mj = 0,0
        def findPalindrome(l,r, bl, br, s):
            i,j = l,r
            while i > bl and j < br and s[i] == s[j]:
                i-=1
                j+=1
            return i+1,j-1
        
        for idx in range(n):
            # check odd palindromes
            oi, oj = findPalindrome(idx, idx, -1, n, s)
            # even
            ei, ej = findPalindrome(idx, idx+1, -1, n, s)

            olen = (oj-oi+1)
            elen = (ej-ei+1)
            if olen > mlen:
                mi, mj = oi, oj
                mlen = olen
            if elen > mlen:
                mi,mj = ei,ej
                mlen = elen
        return s[mi:mj+1]
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q
  1. Shortest Palindrome
    Hard
    Companies: MS, Amazon, TikTok

You are given a string s. You can convert s to a
palindrome
by adding characters in front of it.

Return the shortest palindrome you can find by performing this transformation.

Example 1:

Input: s = “aacecaaa”
Output: “aaacecaaa”

Example 2:

Input: s = “abcd”
Output: “dcbabcd”

Constraints:

0 <= s.length <= 5 * 104
s consists of lowercase English letters only.

O(n^2) acceptable. O(n) space

https://leetcode.com/problems/shortest-palindrome/description/

A
class Solution(object):
    def shortestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        # Key here is to know that to find the longest palindrome starting at 0 
        # in the original string, and prepend reverse of the remaining string. 
        # because as we know if s[i] == s[j] then its a palindrome if s[i+1][j-1] is also a palindrome
        # we find the highest j with i == 0 to make the middle string a palindrome and then fix the rest.

        # Here we compare the reverse string with the forward string to find the longest suffix in 
        # reverse that is equal to prefix in original string.

        #KMP can be used but it's over complicated for interview setting.
        # https://leetcode.com/problems/shortest-palindrome/solutions/60099/ac-in-288-ms-simple-brute-force

        rev = s[::-1]
        # +1 to cover cases where string empty.
        for i in range(len(rev)+1):
            # if this suffix is eq prefix
            if s.startswith(rev[i:]):
                return rev[:i] + s

KMP O(n), O(n)
Explanation

class Solution:
    def shortestPalindrome(self, s: str) -> str:
        rev = s[::-1]
        n = len(s)
        s_new = s + "#" + rev
        nsnew = len(s_new)
        dp = [0] * len(s_new)
        for i in range(1, nsnew):
            t = dp[i-1]
            while s_new[t] != s_new[i] and t > 0:
                t = dp[t-1]
            if s_new[t] == s_new[i]:
                t += 1
            dp[i] = t
        return rev[:n-dp[-1]] + s
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q
  1. Add Strings
    Solved
    Easy
    Topics
    Companies
    Given two non-negative integers, num1 and num2 represented as string, return the sum of num1 and num2 as a string.

You must solve the problem without using any built-in library for handling large integers (such as BigInteger). You must also not convert the inputs to integers directly.

Example 1:

Input: num1 = “11”, num2 = “123”
Output: “134”
Example 2:

Input: num1 = “456”, num2 = “77”
Output: “533”
Example 3:

Input: num1 = “0”, num2 = “0”
Output: “0”

Constraints:

1 <= num1.length, num2.length <= 104
num1 and num2 consist of only digits.
num1 and num2 don’t have any leading zeros except for the zero itself.

https://leetcode.com/problems/add-strings/description/

A
from collections import deque
class Solution(object):
    def addStrings(self, num1, num2):
        """
        :type num1: str
        :type num2: str
        :rtype: str
        """
        i = len(num1) - 1
        j = len(num2) - 1
        base = ord('0')
        carry = 0
        res = deque()
        def getDigit(c):
            return ord(c) - ord('0')

        while i >= 0 or j >= 0:
            c1 = 0 if i < 0 else getDigit(num1[i])
            c2 = 0 if j < 0 else getDigit(num2[j])
            addn = c1 + c2 + carry
            digit = chr(addn%10 + ord('0'))
            carry = addn//10
            res.appendleft(digit)
            i-=1
            j-=1
        if carry:
            res.appendleft(chr(carry + ord('0')))
        
        return "".join(res)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q
  1. Max Consecutive Ones III
    Solved
    Medium
    Topics
    Companies
    Hint
    Given a binary array nums and an integer k, return the maximum number of consecutive 1’s in the array if you can flip at most k 0’s.

Example 1:

Input: nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2
Output: 6
Explanation: [1,1,1,0,0,1,1,1,1,1,1]
Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.
Example 2:

Input: nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], k = 3
Output: 10
Explanation: [0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.

Constraints:

1 <= nums.length <= 105
nums[i] is either 0 or 1.
0 <= k <= nums.length

https://leetcode.com/problems/max-consecutive-ones-iii/description/

A

Expand window till it’s valid, when it’s not, just increment left by one, and keep doing it till the end.
We do not need to shrink window completely because once we have the largest window we can maintain it’s size.

class Solution:
    def longestOnes(self, nums: List[int], k: int) -> int:
        left = 0
        zeros = 0
        for i,c in enumerate(nums):
            zeros += (1-c)
            if zeros > k:
                zeros -= (1-nums[left])
                left += 1
        return i-left + 1
How well did you know this?
1
Not at all
2
3
4
5
Perfectly