Arrays and Pointers Conceptual

Arrays and Pointers Toolkit and Tips

Arrays and Pointers Leetcode Classics

Remove Duplicates From Sorted Array

Main Idea

Intuition

Implementation

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        """
        Non-decreasing order means we can utilize a pointer and greater-than comparison to detect duplicates.
        Don't need to use a hashset.
        """
        p = 0 # p marks last processed elem
        for i in range(1, len(nums)): # i marks elem to process next
            if nums[i] != nums[p]:
                p += 1 # we need to shift p up to the empty spot before replacing
                nums[p] = nums[i]
                
        return p + 1 # return length not index

Two Integer Sum II

Main Idea

Intuition

Implementation

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        """
        Cues
        - Array is sorted
        - We're trying to match a target using sum of elems

        Thus => we use l, r pointer and iterate (3 sum method)
        """
        l, r = 0, len(numbers) - 1
        while l < r:
            curr = numbers[l] + numbers[r]
            if curr > target:
                r -= 1
            elif curr < target:
                l += 1
            else:
                return [l + 1, r + 1]

Three Sum

Main Idea

Intuition

Main Explanation

Implementation

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort() # sort so we can use classic l, r pointer

        ans = []
        for i in range(len(nums)):
            if i > 0 and nums[i] == nums[i - 1]:
                # i pointer duplicate check
                # check if we've alr tried some value as the first num
                continue 
            
            # once we lock an i pointer, we define a window to its right
            # then we search that window with the l and r pointers
            l = i + 1
            r = len(nums) - 1
            while l < r:
                # core logic comparing 
                curr_sum = nums[i] + nums[l] + nums[r]
                
                if curr_sum < 0:
                    l += 1  
                elif curr_sum > 0:
                    r -= 1
                else:
                    # we have a match but once we iterate we need to check duplicates
                    ans.append([nums[i], nums[l], nums[r]])
                    # l pointer duplicate check
                    # check if we've alr tried this num in the second slot
                    l += 1 
                    while nums[l] == nums[l - 1] and l < r:
                        # nums[l] == nums[l - 1] checks duplicate
                        # l < r checks that we're still in a valid l, r window (l & r haven't overlapped)
                        l += 1

                    if r < len(nums) - 1: # if r == len(nums) - 1 => on last elem, no possible duplicate
                        # r always starts at the end no matter where i is
                        # r pointer duplicate check
                        # check if we've alr tried this number in the third slot
                        if nums[r] == nums[r + 1] and l < r:
                            # nums[r] == nums[r + 1] checks duplicate
                            # l < r checks that we're still in a valid l, r window (l & r haven't overlapped)
                            r -= 1
        return ans