Array / String
Table of Contents
- 13. Roman to Integer
- 14. Longest Common Prefix
- 26. Remove Duplicates from Sorted Array
- 27. Remove Element
- 28. Find the Index of the First Occurrence in a String
- 58. Length of Last Word
- 88. Merge Sorted Array
- 121. Best Time to Buy and Sell Stock
- 169. Majority Element
- 2043. Simple Bank System
- 2672. Number of Adjacent Elements With the Same Color
13. Roman to Integer
- LeetCode Link: Roman to Integer
- Difficulty: Easy
- Topic(s): Hash Table, String, Math
- Company: Google
🧠 Problem Statement
Roman numerals are represented by seven different symbols:
I,V,X,L,C,DandM.Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000For example,
2is written asIIin Roman numeral, just two ones added together.12is written asXII, which is simplyX + II. The number27is written asXXVII, which isXX + V + II.Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not
IIII. Instead, the number four is written asIV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written asIX. There are six instances where subtraction is used:
Ican be placed beforeV(5) andX(10) to make 4 and 9.Xcan be placed beforeL(50) andC(100) to make 40 and 90.Ccan be placed beforeD(500) andM(1000) to make 400 and 900.Given a roman numeral, convert it to an integer.
Example 1:
Input: s = "III" Output: 3 Explanation: III = 3.Example 2:
Input: s = "LVIII" Output: 58 Explanation: L = 50, V= 5, III = 3.Example 3:
Input: s = "MCMXCIV" Output: 1994 Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
🧩 Approach
- Create a mapping of Roman numeral symbols to their integer values.
- Initialize a result variable to
0. - Iterate through the string:
- If the current symbol is less than the next symbol, subtract its value from the result.
- Otherwise, add its value to the result.
- Return the result.
💡 Solution
from typing import Dict
class Solution:
def romanToInt(self, s: str) -> int:
"""
Convert a Roman numeral to an integer.
Args:
s (str): The Roman numeral string.
Returns:
int: The integer representation of the Roman numeral.
"""
romans: Dict[str, int] = {
"I": 1,
"V": 5,
"X": 10,
"L": 50,
"C": 100,
"D": 500,
"M": 1000
}
res: int = 0
for i in range(len(s)):
if i + 1 < len(s) and romans[s[i]] < romans[s[i + 1]]:
res -= romans[s[i]]
else:
res += romans[s[i]]
return res
🧮 Complexity Analysis
- Time Complexity:
O(n) - Space Complexity:
O(1)
14. Longest Common Prefix
- LeetCode Link: Longest Common Prefix
- Difficulty: Easy
- Topic(s): String, Trie
- Company: Meta
🧠 Problem Statement
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string
"".Example 1:
Input: strs = ["flower","flow","flight"] Output: "fl"Example 2:
Input: strs = ["dog","racecar","car"] Output: "" Explanation: There is no common prefix among the input strings.
🧩 Approach
- Initialize the result as an empty string.
- Iterate through the characters of the first string.
- For each character, check if it matches the corresponding character in all other strings.
- If a mismatch is found or if the end of any string is reached, return the result.
- If all characters match, append the character to the result.
- Return the result after checking all characters of the first string.
💡 Solution
from typing import List
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
"""
Find the longest common prefix among an array of strings.
Args:
strs (List[str]): The list of strings.
Returns:
str: The longest common prefix.
"""
res: str = ""
for i in range(len(strs[0])):
for s in strs:
if i == len(s) or s[i] != strs[0][i]:
return res
res += strs[0][i]
return res
🧮 Complexity Analysis
- Time Complexity:
O(n * m) - Space Complexity:
O(1)
26. Remove Duplicates from Sorted Array
- LeetCode Link: Remove Duplicates from Sorted Array
- Difficulty: Easy
- Topic(s): Array, Two Pointers
- Company: Microsoft
🧠 Problem Statement
Given an integer array
numssorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. The relative order of the elements should be kept the same. Then return the number of unique elements innums.Consider the number of unique elements of
numsto bek, to get accepted, you need to do the following things:
- Change the array
numssuch that the first k elements ofnumscontain the unique elements in the order they were present innumsinitially. The remaining elements ofnumsare not important as well as the size ofnums.- Return
k.Example 1:
Input: nums = [1,1,2] Output: 2, nums = [1,2,_] Explanation: Your function should return k = 2, with the first two elements of nums being 1 and 2 respectively. It does not matter what you leave beyond the returned k (hence they are underscores).Example 2:
Input: nums = [0,0,1,1,1,2,2,3,3,4] Output: 5, nums = [0,1,2,3,4,_,_,_,_,_] Explanation: Your function should return k = 5, with the first five elements of nums being 0, 1, 2, 3, and 4 respectively. It does not matter what you leave beyond the returned k (hence they are underscores).
🧩 Approach
Use the two-pointer technique:
i: slow pointer, tracks the position of the last unique element.j: fast pointer, scans the array.
Steps:
- Initialize
i = 0. - Iterate
jfrom 1 to end of array. - If
nums[j] != nums[i], it’s a new unique element:- Increment
i - Copy
nums[j]tonums[i]
- Increment
- After the loop, the first
i + 1elements are the unique values.
💡 Solution
from typing import List
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
"""
Remove duplicates from a sorted array in-place and return the new length.
Args:
nums (List[int]): The input sorted array.
Returns:
int: The new length of the array after removing duplicates.
"""
i: int = 0
for j in range(1, len(nums)):
if nums[j] != nums[i]:
i += 1
nums[i] = nums[j]
return i + 1
🧮 Complexity Analysis
- Time Complexity:
O(n) - Space Complexity:
O(1)
27. Remove Element
- LeetCode Link: Remove Element
- Difficulty: Easy
- Topic(s): Array, Two Pointers
- Company: Apple
🧠 Problem Statement
Given an integer array
numsand an integerval, remove all occurrences ofvalinnumsin-place. The order of the elements may be changed. Then return the number of elements innumsthat are not equal toval.Consider the number of elements in
numswhich are not equal tovalbek, to get accepted, you need to do the following things:
- Change the array
numssuch that the firstkelements ofnumscontain the elements which are not equal toval. The remaining elements ofnumsare not important as well as the size of nums.- Return
k.Example 1:
Input: nums = [3,2,2,3], val = 3 Output: 2, nums = [2,2,_,_] Explanation: Your function should return k = 2, with the first two elements of nums being 2. It does not matter what you leave beyond the returned k (hence they are underscores).Example 2:
Input: nums = [0,1,2,2,3,0,4,2], val = 2 Output: 5, nums = [0,1,4,0,3,_,_,_] Explanation: Your function should return k = 5, with the first five elements of nums containing 0, 0, 1, 3, and 4. Note that the five elements can be returned in any order. It does not matter what you leave beyond the returned k (hence they are underscores).
🧩 Approach
Use the two-pointer technique:
- One pointer (
i) scans every element. - Another pointer (
k) keeps track of the position where the next valid (non-val) element should be placed.
Steps:
- Iterate through the array.
- If the current element is not equal to
val, place it at indexkand incrementk. - After the loop,
kwill represent the new length of the array withvalremoved.
💡 Solution
from typing import List
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
"""
Remove all occurrences of `val` in `nums` in-place and return the new length.
Args:
nums (List[int]): The input array.
val (int): The value to be removed.
Returns:
int: The new length of the array after removal.
"""
k: int = 0
for i in range(len(nums)):
if nums[i] != val:
nums[k] = nums[i]
k += 1
return k
🧮 Complexity Analysis
- Time Complexity:
O(n) - Space Complexity:
O(1)
28. Find the Index of the First Occurrence in a String
- LeetCode Link: Find the Index of the First Occurrence in a String
- Difficulty: Easy
- Topic(s): Two Pointers, String, String Matching
- Company: Google
🧠 Problem Statement
Given two strings
needleandhaystack, return the index of the first occurrence ofneedleinhaystack, or-1ifneedleis not part ofhaystack.Example 1:
Input: haystack = "sadbutsad", needle = "sad" Output: 0 Explanation: "sad" occurs at index 0 and 6. The first occurrence is at index 0, so we return 0.Example 2:
Input: haystack = "leetcode", needle = "leeto" Output: -1 Explanation: "leeto" did not occur in "leetcode", so we return -1.
🧩 Approach
Use a simple sliding window approach:
- Iterate through
haystackwith a window of size equal to the length ofneedle. - For each position, check if the substring matches
needle. - If a match is found, return the starting index.
- If no match is found after checking all possible positions, return
-1.
💡 Solution
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
"""
Find the index of the first occurrence of `needle` in `haystack`.
Args:
haystack (str): The string to search in.
needle (str): The substring to search for.
Returns:
int: The index of the first occurrence of `needle` in `haystack`, or -1 if not found.
"""
for i in range(len(haystack) + 1 - len(needle)):
if haystack[i: i + len(needle)] == needle:
return i
return -1
🧮 Complexity Analysis
- Time Complexity:
O(n * m) - Space Complexity:
O(1)
58. Length of Last Word
- LeetCode Link: Length of Last Word
- Difficulty: Easy
- Topic(s): String, String Manipulation
- Company: Amazon
🧠 Problem Statement
Given a string
sconsisting of words and spaces, return the length of the last word in the string.A word is a maximal substring consisting of non-space characters only.
Example 1:
Input: s = "Hello World" Output: 5 Explanation: The last word is "World" with length 5.Example 2:
Input: s = " fly me to the moon " Output: 4 Explanation: The last word is "moon" with length 4.Example 3:
Input: s = "luffy is still joyboy" Output: 6 Explanation: The last word is "joyboy" with length 6.
🧩 Approach
- Split the string
sinto words using thesplit()method, which automatically handles multiple spaces. - Return the length of the last word in the list of words.
💡 Solution
from typing import List
class Solution:
def lengthOfLastWord(self, s: str) -> int:
"""
Calculate the length of the last word in a string.
Args:
s (str): The input string.
Returns:
int: The length of the last word.
"""
words: List[str] = s.split()
return len(words[-1])
🧮 Complexity Analysis
- Time Complexity:
O(n) - Space Complexity:
O(n)
88. Merge Sorted Array
- LeetCode Link: Merge Sorted Array
- Difficulty: Easy
- Topic(s): Array, Two Pointers, Sorting
- Company: Meta
🧠 Problem Statement
You are given two integer arrays
nums1andnums2, sorted in non-decreasing order, and two integersmandn, representing the number of elements innums1andnums2respectively.Merge
nums1andnums2into a single array sorted in non-decreasing order.The final sorted array should not be returned by the function, but instead be stored inside the array
nums1. To accommodate this,nums1has a length ofm + n, where the firstmelements denote the elements that should be merged, and the lastnelements are set to0and should be ignored.nums2has a length ofn.Example 1:
Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 Output: [1,2,2,3,5,6] Explanation: The arrays we are merging are [1,2,3] and [2,5,6]. The result of the merge is [1,2,2,3,5,6] with the underlined elements coming from nums1.Example 2:
Input: nums1 = [1], m = 1, nums2 = [], n = 0 Output: [1] Explanation: The arrays we are merging are [1] and []. The result of the merge is [1].Example 3:
Input: nums1 = [0], m = 0, nums2 = [1], n = 1 Output: [1] Explanation: The arrays we are merging are [] and [1]. The result of the merge is [1]. Note that because m = 0, there are no elements in nums1. The 0 is only there to ensure the merge result can fit in nums1.
🧩 Approach
Use three pointers:
midxpoints to the last valid element innums1(m - 1)nidxpoints to the last element innums2(n - 1)rightpoints to the last index innums1(m + n - 1)
Compare elements from the back and place the larger one at index right. Decrement pointers accordingly.
Repeat until nidx reaches 0 (no need to worry about midx, since the rest are already in place).
💡 Solution
from typing import List
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Merge two sorted arrays `nums1` and `nums2` into `nums1` in-place.
Args:
nums1 (List[int]): The first sorted array with enough space to hold the elements of `nums2`.
m (int): The number of elements in `nums1`.
nums2 (List[int]): The second sorted array.
n (int): The number of elements in `nums2`.
Returns:
None: The result is stored in `nums1`.
"""
midx: int = m - 1
nidx: int = n - 1
right: int = m + n - 1
while nidx >= 0:
if midx >= 0 and nums1[midx] > nums2[nidx]:
nums1[right] = nums1[midx]
midx -= 1
else:
nums1[right] = nums2[nidx]
nidx -= 1
right -= 1
🧮 Complexity Analysis
- Time Complexity:
O(m + n) - Space Complexity:
O(1)
121. Best Time to Buy and Sell Stock
- LeetCode Link: Best Time to Buy and Sell Stock
- Difficulty: Easy
- Topic(s): Array, Dynamic Programming
- Company: Amazon
🧠 Problem Statement
You are given an array
priceswhereprices[i]is the price of a given stock on theithday.You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.
Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return
0.Example 1:
Input: prices = [7,1,5,3,6,4] Output: 5 Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.Example 2:
Input: prices = [7,6,4,3,1] Output: 0 Explanation: In this case, no transactions are done and the max profit = 0.
🧩 Approach
Dynamic programming approach:
-
Initialize
profitto0andlowestto the first price. -
Iterate through the prices:
- For each price, calculate the potential profit by subtracting
lowestfrom the current price. - Update
profitif the calculated profit is greater than the currentprofit. - Update
lowestto be the minimum of the current price andlowest.
- For each price, calculate the potential profit by subtracting
-
Return the
profit.
This approach ensures that we always consider the lowest price seen so far, allowing us to calculate the maximum profit efficiently.
💡 Solution
from typing import List
class Solution:
def maxProfit(self, prices: List[int]) -> int:
"""
Calculate the maximum profit from a single buy and sell transaction.
Args:
prices (List[int]): The list of stock prices.
Returns:
int: The maximum profit achievable, or 0 if no profit can be made.
"""
profit: int = 0
lowest: int = prices[0]
for price in prices:
profit = max(profit, price - lowest)
lowest = min(lowest, price)
return profit
🧮 Complexity Analysis
- Time Complexity:
O(n) - Space Complexity:
O(1)
169. Majority Element
- LeetCode Link: Majority Element
- Difficulty: Easy
- Topic(s): Array, Hash Table, Divide and Conquer, Counting
- Company: Apple
🧠 Problem Statement
Given an array
numsof sizen, return the majority element.The majority element is the element that appears more than
⌊n / 2⌋times. You may assume that the majority element always exists in the array.Example 1:
Input: nums = [3,2,3] Output: 3Example 2:
Input: nums = [2,2,1,1,1,2,2] Output: 2
🧩 Approach
Boyer-Moore Voting Algorithm:
- Initialize a
count = 0andcandidate = None. - Iterate through the array:
- If
count == 0, setcandidate = current element - If
current element == candidate, incrementcount - Else, decrement
count
- If
- At the end,
candidateis the majority element.
This works because the majority element appears more than all others combined.
💡 Solution
from typing import List
class Solution:
def majorityElement(self, nums: List[int]) -> int:
"""
Find the majority element in an array using Boyer-Moore Voting Algorithm.
Args:
nums (List[int]): The input array.
Returns:
int: The majority element.
"""
count: int = 0
candidate: int = 0
for num in nums:
if count == 0:
candidate = num
if num == candidate:
count += 1
else:
count -= 1
return candidate
🧮 Complexity Analysis
- Time Complexity:
O(n) - Space Complexity:
O(1)
2043. Simple Bank System
- LeetCode Link: Simple Bank System
- Difficulty: Medium
- Topic(s): Design, Array
- Company: Capital One
🧠 Problem Statement
You have been tasked with writing a program for a popular bank that will automate all its incoming transactions (transfer, deposit, and withdraw). The bank has n accounts numbered from 1 to n. The initial balance of each account is stored in a 0-indexed integer array balance, with the (i + 1)th account having an initial balance of balance[i].
Execute all the valid transactions. A transaction is valid if:
- The given account number(s) are between
1andn, and - The amount of money withdrawn or transferred from is less than or equal to the balance of the account.
Implement the Bank class:
Bank(long[] balance)Initializes the object with the 0-indexed integer array balance.boolean transfer(int account1, int account2, long money)Transfersmoneydollars from the account numberedaccount1to the account numberedaccount2. Returntrueif the transaction was successful,falseotherwise.boolean deposit(int account, long money)Depositmoneydollars into the account numberedaccount. Returntrueif the transaction was successful,falseotherwise.boolean withdraw(int account, long money)Withdrawmoneydollars from the account numberedaccount. Returntrueif the transaction was successful,falseotherwise.
Example 1:
Input
["Bank", "withdraw", "transfer", "deposit", "transfer", "withdraw"]
[[[10, 100, 20, 50, 30]], [3, 10], [5, 1, 20], [5, 20], [3, 4, 15], [10, 50]]
Output
[null, true, true, true, false, false]
Explanation
Bank bank = new Bank([10, 100, 20, 50, 30]);
bank.withdraw(3, 10); // return true, account 3 has a balance of $20, so it is valid to withdraw $10.
// Account 3 has $20 - $10 = $10.
bank.transfer(5, 1, 20); // return true, account 5 has a balance of $30, so it is valid to transfer $20.
// Account 5 has $30 - $20 = $10, and account 1 has $10 + $20 = $30.
bank.deposit(5, 20); // return true, it is valid to deposit $20 to account 5.
// Account 5 has $10 + $20 = $30.
bank.transfer(3, 4, 15); // return false, the current balance of account 3 is $10,
// so it is invalid to transfer $15 from it.
bank.withdraw(10, 50); // return false, it is invalid because account 10 does not exist.
🧩 Approach
- Initialize the
Bankclass with the given balances. - Implement the
transfermethod to check for valid accounts and sufficient balance before transferring money. - Implement the
depositmethod to add money to the specified account if valid. - Implement the
withdrawmethod to deduct money from the specified account if valid.
💡 Solution
from typing import List
class Bank:
def __init__(self, balance: List[int]):
"""
Initialize the Bank with the given balances.
Args:
balance (List[int]): The initial balances of the accounts.
"""
self.balance: List[int] = balance
def transfer(self, account1: int, account2: int, money: int) -> bool:
"""
Transfer money from account1 to account2 if valid.
Args:
account1 (int): The account number to transfer money from.
account2 (int): The account number to transfer money to.
money (int): The amount of money to transfer.
Returns:
bool: True if the transfer was successful, False otherwise.
"""
if (
account1 > len(self.balance)
or account2 > len(self.balance)
or self.balance[account1 - 1] < money
):
return False
self.balance[account1 - 1] -= money
self.balance[account2 - 1] += money
return True
def deposit(self, account: int, money: int) -> bool:
"""
Deposit money into the specified account if valid.
Args:
account (int): The account number to deposit money into.
money (int): The amount of money to deposit.
Returns:
bool: True if the deposit was successful, False otherwise.
"""
if account > len(self.balance):
return False
self.balance[account - 1] += money
return True
def withdraw(self, account: int, money: int) -> bool:
"""
Withdraw money from the specified account if valid.
Args:
account (int): The account number to withdraw money from.
money (int): The amount of money to withdraw.
Returns:
bool: True if the withdrawal was successful, False otherwise.
"""
if account > len(self.balance) or self.balance[account - 1] < money:
return False
self.balance[account - 1] -= money
return True
🧮 Complexity Analysis
- Time Complexity:
O(1) - Space Complexity:
O(1)
2672. Number of Adjacent Elements With the Same Color
- LeetCode Link: Number of Adjacent Elements With the Same Color
- Difficulty: Easy
- Topic(s): Array, Simulation
- Company: Capital One
🧠 Problem Statement
You are given an integer
nrepresenting anarraycolors of lengthnwhere all elements are set to 0’s meaning uncolored. You are also given a 2D integer arrayquerieswherequeries[i] = [indexi, colori]. For theithquery:Set
colors[indexi]tocolori. Count the number of adjacent pairs incolorswhich have the same color (regardless ofcolori). Return an arrayanswerof the same length asquerieswhereanswer[i]is the answer to theithquery.Example 1:
Input: n = 4, queries = [[0,2],[1,2],[3,1],[1,1],[2,1]] Output: [0,1,1,0,2] Explanation: Initially array colors = [0,0,0,0], where 0 denotes uncolored elements of the array. After the 1st query colors = [2,0,0,0]. The count of adjacent pairs with the same color is 0. After the 2nd query colors = [2,2,0,0]. The count of adjacent pairs with the same color is 1. After the 3rd query colors = [2,2,0,1]. The count of adjacent pairs with the same color is 1. After the 4th query colors = [2,1,0,1]. The count of adjacent pairs with the same color is 0. After the 5th query colors = [2,1,1,1]. The count of adjacent pairs with the same color is 2.Example 2:
Input: n = 1, queries = [[0,100000]] Output: [0] Explanation: After the 1st query colors = [100000]. The count of adjacent pairs with the same color is 0.
🧩 Approach
- Initialize a count variable to keep track of adjacent pairs with the same color.
- Create an array
numsof sizeninitialized to0to represent uncolored elements. - For each query:
- Check the previous and next elements of the index being colored.
- If the current element is already colored and matches the previous or next element, decrement the count.
- Update the color of the current index.
- If the new color matches the previous or next element, increment the count.
- Append the current count to the result list after each query.
💡 Solution
from typing import List
class Solution:
def colorTheArray(self, n: int, queries: List[List[int]]) -> List[int]:
count: int = 0
res: List[int] = []
nums: List[int] = [0 for _ in range(n)]
for idx, color in queries:
prev: int = nums[idx - 1] if idx > 0 else 0
nxt: int = nums[idx + 1] if idx < n - 1 else 0
if nums[idx] and nums[idx] == prev:
count -= 1
if nums[idx] and nums[idx] == nxt:
count -= 1
nums[idx] = color
if nums[idx] and nums[idx] == prev:
count += 1
if nums[idx] and nums[idx] == nxt:
count += 1
res.append(count)
return res
🧮 Complexity Analysis
- Time Complexity:
O(n) - Space Complexity:
O(n)