Insights Repo.

Data Structures and Algorithms

0

0
0
Cover Image for Data Structures and Algorithms
Gagan S
Gagan S

I’ve always believed that mastering Data Structures and Algorithms (DSA) is less about memorizing patterns and more about understanding how and why things work under the hood. As I work through various LeetCode problems—especially the LeetCode 75 series—I’ve found it helpful to document my solutions, thought processes, and the concepts I’m revisiting along the way.

This blog is my personal space to track my progress, consolidate what I’ve learned, and make it easier to revise these ideas later. It’s not just a collection of answers but also a reflection of how I approach problems, where I struggled, and how I optimized my solutions. Hopefully, this will also serve as a useful reference for anyone walking a similar path in their DSA journey.


Arrays

  1. Merge Strings Alternately
def mergeAlternately(self, word1: str, word2: str) -> str:
    i = 0
    word = ""
    max_len = max(len(word1), len(word2))
    while(i < max_len):
        if i < len(word1):
            word = word + word1[i]
        if i < len(word2):
            word = word + word2[i]
        i += 1

    return word
  1. Greatest Common Divisor of Strings
def gcdOfStrings(self, str1: str, str2: str) -> str:
    if str1 + str2 != str2 + str1:
        return ""

    def gcd(a, b):
        while b != 0:
            a, b = b, a % b
        return a

    if a == 0:
        return ""

    return str1[:gcd(len(str1), len(str2))]
  1. Kids With the Greatest Number of Candies
def kidsWithCandies(self, candies: List[int], extraCandies: int) -> List[bool]:
    max_candies = max(candies)
    res = []
    for i in range(len(candies)):
        if candies[i] + extraCandies >= max_candies:
            res.append(True)
        else:
            res.append(False)
    return res
  1. Can Place Flowers
def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
    count = 0
    for i in range(len(flowerbed)):
        left = i == 0 or flowerbed[i-1] == 0
        right = i == len(flowerbed) - 1 or flowerbed[i+1] == 0

        if left and right and flowerbed[i] == 0:
            flowerbed[i] = 1
            count += 1
    
    return count >= n
  1. Reverse Vowels of a String
def reverseVowels(self, s: str) -> str:
    s = list(s)
    n = len(s)

    vowels = set('AEIOUaeiou')

    l = 0
    r = n - 1

    while(l<r):
        while l<r and s[l] not in vowels:
            l += 1
        while l<r and s[r] not in vowels:
            r -= 1

        s[l], s[r] = s[r], s[l]
        l += 1
        r -= 1

    return "".join(s)
  1. Delete Characters to Make Fancy String
def makeFancyString(self, s: str) -> str:
    ans = s[0]
    cnt = 1
    for i in range(1, len(s)):
        if s[i] == ans[-1]:
            cnt += 1
            if cnt < 3:
                ans += s[i]
        else:
            cnt = 1
            ans += s[i]
    return ans
  1. Reverse Words in a String
def reverseWords(self, s: str) -> str:
    words = s.strip().split()
    words.reverse()
    return " ".join(words)

def reverseWords(self, s: str) -> str:
    s = s + " "
    ns = ""
    ts = ""
    for x in s:
        if x != " ":
            ts = ts + x
        else:
            ns = ts.strip() + " " + ns.strip()
            ts = ""
    return ns.strip()         
  1. Product of Array Except Self
def productExceptSelf(self, nums: List[int]) -> List[int]:
    output = [1] * len(nums)

    left = 1
    for i in range(len(nums)):
        output[i] = output[i] * left
        left = left * nums[i]
    
    right = 1
    for i in range(len(nums)-1, -1, -1):
        output[i] = output[i] * right
        right = right * nums[i]

    return output     
  1. Increasing Triplet Subsequence
def increasingTriplet(self, nums: List[int]) -> bool:
    first = second = max(nums)
    for num in nums:
        if num <= first:
            first = num
        elif num <= second:
            second = num
        else:
            return True
    return False 
  1. String Compression
def compress(self, chars: List[str]) -> int:
    ans = 0
    i = 0

    while(i < len(chars)):
        letter = chars[i]
        count = 0

        while(i < len(chars) and chars[i] == letter):
            count += 1
            i += 1

        chars[ans] = letter
        ans += 1

        if count > 1:
            for c in str(count):
                chars[ans] = c
                ans += 1

    return ans
  1. Maximum Erasure Value
def maximumUniqueSubarray(self, nums: List[int]) -> int:
    seen = set()
    left = 0
    current_sum = 0
    max_sum = 0
    
    for right in range(len(nums)):
        while nums[right] in seen:
            current_sum -= nums[left]
            seen.remove(nums[left])
            left += 1
        current_sum += nums[right]
        seen.add(nums[right])
        max_sum = max(max_sum, current_sum)
    
    return max_sum