Basic linear data structure
# https://github.com/yennanliu/CS_basics/blob/master/doc/cheatsheet/python_trick.md
#-----------------------------------------------------------------------------------------------------
# example 7 : itertools.islice : slice on iterator
#-----------------------------------------------------------------------------------------------------
# https://docs.python.org/3/library/itertools.html#itertools.islice
# syntax : itertools.islice(seq, [start,] stop [, step])
6]: x = itertools.islice(range(10), 0, 9, 2)
In [
7]: print (list(x))
In [0, 2, 4, 6, 8]
[
18]: y = itertools.islice(range(10), 0, 10, 3)
In [print (list(y))
...: 0, 3, 6, 9] [
=[[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]]
p27]: [[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]]
Out[28]: p.insert(1, [6,1])
In [29]: p
In [29]: [[7, 0], [6, 1], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]] Out[
=[[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]]
p
4]: p
In [4]: [[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]]
Out[
5]: p.remove([7, 1])
In [
6]: p
In [6]: [[7, 0], [6, 1], [5, 0], [5, 2], [4, 4]] Out[
7]: p
In [7]: [[7, 0], [6, 1], [5, 0], [5, 2], [4, 4]]
Out[
8]: [7,0] in p
In [8]: True Out[
# tail
9]: p
In [9]: [[7, 0], [6, 1], [5, 0], [5, 2], [4, 4]]
Out[
10]: p.append([0,0])
In [
11]: p
In [11]: [[7, 0], [6, 1], [5, 0], [5, 2], [4, 4], [0, 0]] Out[
# Pattern :
# V1
= lambda x : <your_sorting_func>)
_array.sort(key
# V2
sorted(_array, key = lambda x : <your_sorting_func>)
# 049 Group Anagrams
= ["eat","tea","tan","ate","nat","bat"]
strs = lambda x : ''.join(sorted(x)) )
strs.sort(key print (strs)
# ['bat', 'eat', 'tea', 'ate', 'tan', 'nat']
### NOTE can use this as well
sorted(strs, key = lambda x : ''.join(sorted(x)))
# LC 341
# V0
class NestedIterator(object):
def __init__(self, nestedList):
self.queue = []
def getAll(nests):
for nest in nests:
if nest.isInteger():
self.queue.append(nest.getInteger())
else:
getAll(nest.getList())
getAll(nestedList)
def next(self):
return self.queue.pop(0)
def hasNext(self):
return len(self.queue)
# default py
# V1
def flatten_array(_array):
= []
r def helper(_array):
for i in _array:
if type(i) == int:
print (i)
r.append(i)else:
helper(i)
helper(_array)return r
= [1,0, [1,2,[4,[5,[6,[7]]]]]]#[1,[4,[6]]] #[[1,1],2,[1,1]]
_input
= flatten_array(_input)
res print ("res = " + str(res))
# V2
# https://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists
def flatten(L):
for item in L:
try:
yield from flatten(item)
except TypeError:
yield item
= flatten(_input)
r2 = [x for x in r2]
r2_ print (r2_)
# V3
def flatten2(L):
for item in L:
try:
yield from flatten2(item)
except:
yield item
= flatten2(_input)
r3 = [x for x in r3]
r3_ print (r3_)
// java
// algorithm book (labu) p.355
//------------------------------------------
// implement NestedInteger data structure
//------------------------------------------
public class NestedInteger {
private Integer val;
private List<NestedInteger> list;
public NestedInteger(Integer val){
this.val = val;
this.list = null;
}
public NestedInteger(List<NestedInteger> list){
this.list = list;
this.val = null;
}
// if saved value is integer, return true, else false
public boolean isIntger(){
return val != null;
}
// if saved value is integer, return it, else return null
public Integer getInteger(){
return this.val;
}
// if saved value is array, return it, else return null
public List<NestedInteger> getList(){
return this.list;
}
}
// java
// LC 341
// algorithm book (labu) p.357
//-----------------------------------------------------------
// NestedInteger solution V1 : via tree algorithm
//-----------------------------------------------------------
class NestedIterator implements Iterator<Integer>{
private Iterator<Integer> it;
public NestedInteger(List<NestedInteger> nestedList){
// save flatten result
List<Integer> result = new LinkedList<>();
for (NestedInteger node: nestedList){
// start from each node and proceed
traverse(node, result);
}
// get result's iterator
this.it = result.iterator();
}
public Integer next(){
return it.next();
}
public boolean hasNext(){
return it.hasNext();
}
// traverse tree with root as root, and add nodes to result array
private void traverse(NestedInteger root, List<Integer> result){
if (root.isIntger()){
// arrive root node
.add(root.getInteger());
resultreturn;
}
// traverse framework
for (NestedInteger child: root.getList()){
traverse(child, result);
}
}
}
// java
// LC 341
// algorithm book (labu) p.358
//-----------------------------------------------------------
// NestedInteger solution V2 : via lazy calling
//-----------------------------------------------------------
public class NestedIterator implements Iterator<Integer>{
private LinkedList<NestedInteger> list;
public NestedInteger(List<NestedInteger> nestedList){
// use LinkedList, for good performance in below op
= new LinkedList<>(nestedList);
list }
public Integer next(){
// hasNext method make sure 1st element must be Integer type
return list.remove(0).getInteger();
}
public boolean hasNext(){
// for loop split elements in array until 1st element is Integer type
while (!list.isEmpty() && list.get(0).isIntger()){
// when 1st element is array type, go into the loop
List<NestedInteger> first = list.remove(0).getList();
// flatten 1st array, and add to "start" in ordering
for (int i = first.size() - 1; i >= 0; i--){
.addFirst(first.get(i));
list}
}
return !list.isEmpty();
}
}
= [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
y print (y)
= lambda x : (-x[0], x[1]))
y.sort(key print (y)
# [[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]]
# [[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]]
#--------------------
# example 1
#--------------------
# 2 array : s,t
# len(s) = 10, len(t) = 7
# or
# len(s) = 10, len(t) = 11
if len(s) > len(t):
= t,s
s,t
for i in range(len(s)):
print (s[i], t[i])
#--------------------
# example 2
#--------------------
# LC 165
class Solution:
def compareVersion(self, version1: str, version2: str) -> int:
= version1.split('.')
nums1 = version2.split('.')
nums2 = len(nums1), len(nums2)
n1, n2
# NOTE here !!!
# compare versions
for i in range(max(n1, n2)):
= int(nums1[i]) if i < n1 else 0
i1 = int(nums2[i]) if i < n2 else 0
i2 if i1 != i2:
return 1 if i1 > i2 else -1
# the versions are equal
return 0
# LC 670
# V0'
# IDEA : BRUTE FORCE
# NOTE : there is also 2 pointers solution :
# -> https://github.com/yennanliu/CS_basics/blob/master/leetcode_python/Array/maximum-swap.py#L49
# NOTE : ans = A[:]
# A[:] is a `shallow copy` syntax in python,
# it will copy "parent obj" (not child obj) to the other instance
# so the changes ("parent obj" only) in original instance will NOT affect the copied instance
# https://stackoverflow.com/questions/4081561/what-is-the-difference-between-list-and-list-in-python
# https://github.com/yennanliu/til#20210923
class Solution(object):
def maximumSwap(self, num):
= list(str(num))
A = A[:]
ans for i in range(len(A)):
for j in range(i+1, len(A)):
= A[j], A[i]
A[i], A[j] if A > ans:
= A[:]
ans = A[j], A[i]
A[i], A[j]
return int("".join(ans))
# LC 406 Queue Reconstruction by Height
class Solution(object):
def reconstructQueue(self, people):
= lambda x : (-x[0], x[1]))
people.sort(key = []
res for p in people:
"""
py insert syntax
# syntax :
# https://github.com/yennanliu/CS_basics/blob/master/doc/cheatsheet/python_trick.md#1-6-insert-into-array-in-place
# arr.insert(<index>,<value>)
"""
1], p)
res.insert(p[return res
# 238 Product of Array Except Self
# IDEA :
# SINCE output[i] = (x0 * x1 * ... * xi-1) * (xi+1 * .... * xn-1)
# -> SO DO A 2 LOOP
# -> 1ST LOOP : GO THROGH THE ARRAY (->) : (x0 * x1 * ... * xi-1)
# -> 2ND LOOP : GO THROGH THE ARRAY (<-) : (xi+1 * .... * xn-1)
# e.g.
# given [1,2,3,4], return [24,12,8,6].
# -> output = [2*3*4, 1,1,1] <-- 2*3*4 (right of 1: 2,3,4)
# -> output = [2*3*4, 1*3*4,1,1] <-- 1*3*4 (left of 2 :1, right of 2: 3,4)
# -> output = [2*3*4, 1*3*4,1*2*4,1] <-- 1*2*4 (left of 3: 1,2 right of 3 : 4)
# -> output = [2*3*4, 1*3*4,1*2*4,1*2*3] <-- 1*2*3 (left of 4 : 1,2,3)
# -> final output = [2*3*4, 1*3*4,1*2*4,1*2*3] = [24,12,8,6]
class Solution:
def productExceptSelf(self, nums):
= len(nums)
size = [1] * size
output = 1
left for x in range(size - 1):
*= nums[x]
left + 1] *= left
output[x = 1
right for x in range(size - 1, 0, -1):
*= nums[x]
right - 1] *= right
output[x return output
# 670 Maximum Swap
class Solution(object):
def maximumSwap(self, num):
"""
:type num: int
:rtype: int
"""
# BE AWARE OF IT
= list(str(num))
digits = 0, 0
left, right = len(digits)-1
max_idx for i in range(len(digits))[::-1]:
# BE AWARE OF IT
if digits[i] > digits[max_idx]:
= i
max_idx # BE AWARE OF IT
# if current digit > current max digit -> swap them
elif digits[max_idx] > digits[i]:
= i, max_idx # if current max digit > current digit -> save current max digit to right idnex, and save current index to left
left, right = digits[right], digits[left] # swap left and right when loop finished
digits[left], digits[right] return int("".join(digits))
# LC 121 Best Time to Buy and Sell Stock
# V0
# IDEA : array op + problem understanding
class Solution(object):
def maxProfit(self, prices):
if len(prices) == 0:
return 0
### NOTE : we define 1st minPrice as prices[0]
= prices[0]
minPrice = 0
maxProfit ### NOTE : we only loop prices ONCE
for p in prices:
# only if p < minPrice, we get minPrice
if p < minPrice:
= p
minPrice ### NOTE : only if p - minPrice > maxProfit, we get maxProfit
elif p - minPrice > maxProfit:
= p - minPrice
maxProfit return maxProfit
# LC 1375. Bulb Switcher III
# V0
class Solution:
def numTimesAllBlue(self, light):
= 0
max_bulb_ind = 0
count = 0
turnedon_bulb
for bulb in light:
= max(max_bulb_ind,bulb)
max_bulb_ind += 1
turnedon_bulb if turnedon_bulb == max_bulb_ind:
+= 1
count
return count
# LC 1041. Robot Bounded In Circle
# V0
# IDEA : math + array
class Solution:
def isRobotBounded(self, instructions):
"""
NOTE !!! we make direction as below
c == 'L': move LEFT : [0,-1]
c == 'R': move RIGHT : [0,1]
"""
= [[0,1], [1,0], [0,-1], [-1,0]]
dirs = 0;
x = 0;
y = 0;
idx for c in instructions:
print ("c = " + str(c) + " idx = " + str(idx))
"""
NOTE !!! since we need to verify if robot back to start point
-> we use (idx + k) % 4 for detecting cyclic cases
"""
if c == 'L':
= (idx + 3) % 4
idx elif c == 'R':
= (idx + 1) % 4
idx elif c == 'G':
= x + dirs[idx][0]
x = y + dirs[idx][1]
y return (x == 0 and y ==0) or idx !=0
# LC 1567 Maximum Length of Subarray With Positive Product
# V0
class Solution:
def getMaxLen(self, nums):
= None, -1
first_neg, zero = neg = 0
mx for i,v in enumerate(nums):
if v == 0:
= None, i, 0
first_neg, zero, neg continue
if v < 0:
+= 1
neg if first_neg == None:
= i
first_neg = zero if not neg % 2 else first_neg if first_neg != None else 10**9
j = max(mx, i-j)
mx return mx
# V0'
# IDEA : 2 POINTERS
class Solution:
def getMaxLen(self, nums):
= 0
res = -1 # most recent 0
k = -1 # first negative after most recent 0
j = 0 # count of negatives after most recent 0
cnt for i, n in enumerate(nums):
if n == 0:
= i
k = i
j = 0
cnt elif n < 0:
+= 1
cnt if cnt % 2 == 0:
= max(res, i - k)
res else:
if cnt == 1:
= i
j else:
= max(res, i - j)
res else:
if cnt % 2 == 0:
= max(res, i - k)
res else:
= max(res, i - j)
res return res
# LC 1109. Corporate Flight Bookings
# V1
# IDEA : ARRAY + prefix sum
# https://leetcode.com/problems/corporate-flight-bookings/discuss/328856/JavaC%2B%2BPython-Sweep-Line
# IDEA :
# Set the change of seats for each day.
# If booking = [i, j, k],
# it needs k more seat on ith day,
# and we don't need these seats on j+1th day.
# We accumulate these changes then we have the result that we want.
# Complexity
# Time O(booking + N) for one pass on bookings
# Space O(N) for the result
class Solution:
def corpFlightBookings(self, bookings, n):
= [0] * (n + 1)
res for i, j, k in bookings:
- 1] += k
res[i -= k
res[j] for i in range(1, n):
+= res[i - 1]
res[i] return res[:-1]
# V1''
# IDEA : ARRAY
# https://leetcode.com/problems/corporate-flight-bookings/discuss/328893/Short-python-solution
# IDEA : Simply use two arrays to keep track of how many bookings are added for every flight.
class Solution:
def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]:
= [0]*n
opens = [0]*n
closes
for e in bookings:
0]-1] += e[2]
opens[e[1]-1] += e[2]
closes[e[
= [0]*n, 0
ret, tmp for i in range(n):
+= opens[i]
tmp = tmp
ret[i] -= closes[i]
tmp
return ret
# LC 41. First Missing Positive
# V1'
# IDEA : Index as a hash key.
# https://leetcode.com/problems/first-missing-positive/solution/
# /doc/pic/first-missing-positive.png
class Solution:
def firstMissingPositive(self, nums: List[int]) -> int:
= len(nums)
n
# Base case.
if 1 not in nums:
return 1
# Replace negative numbers, zeros,
# and numbers larger than n by 1s.
# After this convertion nums will contain
# only positive numbers.
for i in range(n):
if nums[i] <= 0 or nums[i] > n:
= 1
nums[i]
# Use index as a hash key and number sign as a presence detector.
# For example, if nums[1] is negative that means that number `1`
# is present in the array.
# If nums[2] is positive - number 2 is missing.
for i in range(n):
= abs(nums[i])
a # If you meet number a in the array - change the sign of a-th element.
# Be careful with duplicates : do it only once.
if a == n:
0] = - abs(nums[0])
nums[else:
= - abs(nums[a])
nums[a]
# Now the index of the first positive number
# is equal to first missing positive.
for i in range(1, n):
if nums[i] > 0:
return i
if nums[0] > 0:
return n
return n + 1
# LC 334 Increasing Triplet Subsequence
# V0
# IDEA : MAINTAIN var first, second
# AND GO THROUGH nums to check if there exists x (on the right hand side of a, b )
# such that x > second > first
class Solution(object):
def increasingTriplet(self, nums):
"""
NOTE !!! we init first, second as POSITIVE float('inf')
"""
= float('inf')
first = float('inf')
second # loop with normal ordering
for num in nums:
if num <= first: # min num
= num
first elif num <= second: # 2nd min num
= num
second else: # 3rd min num
return True
return False
# LC 41. First Missing Positive
# V0
# IDEA : for loop + while loop + problem understanding
class Solution:
def firstMissingPositive(self, nums):
for i, n in enumerate(nums):
if n < 0:
continue
else:
while n <= len(nums) and n > 0:
= nums[n-1]
tmp -1] = float('inf')
nums[n= tmp
n for i in range(len(nums)):
if nums[i] != float('inf'):
return i+1
return len(nums)+1
# LC 189. Rotate Array
# V0
# IDEA : pop + insert
class Solution(object):
def rotate(self, nums, k):
= len(nums)
_len = k % _len
k while k > 0:
= nums.pop(-1)
tmp 0, tmp)
nums.insert(-= 1
k
# V0'
# IDEA : SLICE (in place)
class Solution(object):
def rotate(self, nums, k):
# edge case
if k == 0 or not nums or len(nums) == 1:
return nums
### NOTE this
= k % len(nums)
k if k == 0:
return nums
"""
NOTE this !!!!
"""
= nums[-k:], nums[:-k]
nums[:k], nums[k:] return nums
# LC 251. Flatten 2D Vector
# V0
# IDEA : ARRAY OP
class Vector2D:
def __init__(self, v):
# We need to iterate over the 2D vector, getting all the integers
# out of it and putting them into the nums list.
self.nums = []
for inner_list in v:
for num in inner_list:
self.nums.append(num)
# We'll keep position 1 behind the next number to return.
self.position = -1
def next(self):
# Move up to the current element and return it.
self.position += 1
return self.nums[self.position]
def hasNext(self):
# If the next position is a valid index of nums, return True.
return self.position + 1 < len(self.nums)
// java
// LC 849. Maximize Distance to Closest Person
// V0-1
// IDEA (fixed by gpt)
/**
* IDEA :
*
* Explanation of the Code:
* 1. Initial Setup:
* • lastOccupied keeps track of the index of the last seat occupied by a person.
* • maxDistance is initialized to 0 to store the maximum distance found.
*
* 2. Iterate Through the Array:
* • When a seat is occupied (seats[i] == 1):
* • If it’s the first occupied seat, calculate the distance from the start of the array to this seat (i).
* • Otherwise, calculate the middle distance between the current and the last occupied seat using (i - lastOccupied) / 2.
*
* 3. Check the Last Segment:
* • If the last seat is empty, calculate the distance from the last occupied seat to the end of the array (seats.length - 1 - lastOccupied).
*
* 4. Return the Maximum Distance:
* • The value of maxDistance at the end of the loop is the answer.
*
*
* Example :
* input : seats = [1, 0, 0, 0, 1, 0, 1]
*
* Execution Steps:
* 1. First occupied seat at index 0 → Distance to start = 0.
* 2. Second occupied seat at index 4 → Middle distance = (4 - 0) / 2 = 2.
* 3. Third occupied seat at index 6 → Middle distance = (6 - 4) / 2 = 1.
* 4. No empty seats after the last occupied seat.
* 5. maxDistance = 2.
*
* output: 2
*
*/
/**
* Cases
*
* Case 1) 0001 ( all "0" till meat first "1")
* Case 2) 1001001 (all "0" are enclosed by "1")
* Case 3) 1001000 (there are "0" that NOT enclosed by "1" on the right hand side)
*
*/
public int maxDistToClosest_0_1(int[] seats) {
int maxDistance = 0;
int lastOccupied = -1;
// Traverse the array to calculate maximum distances
for (int i = 0; i < seats.length; i++) {
/** NOTE !!! handle the seat val == 1 cases */
if (seats[i] == 1) {
if (lastOccupied == -1) {
// Handle the case where the `first` occupied seat is found
/**
* NOTE !!!
*
* for handling below case:
*
* e.g. : 0001
*
* (so, elements are all "0" till first visit "1")
* in this case, we still can get put a person to seat, and get distance
*
*/
= i; // Distance from the start to the first occupied seat
maxDistance } else {
// Calculate the distance to the closest person for the middle segment
/** NOTE !!! need to divided by 2, since the person need to seat at `middle` seat */
= Math.max(maxDistance, (i - lastOccupied) / 2);
maxDistance }
= i;
lastOccupied }
}
// Handle the case where the last segment is empty
/**
* NOTE !!!
*
* the condition is actually quite straightforward,
* just need to check if the last element in array is "0"
* if is "0", means the array is NOT enclosed by "1"
* then we need to handle such case
* (example as below)
*
* e.g. 100010000
*
*/
if (seats[seats.length - 1] == 0) {
= Math.max(maxDistance, seats.length - 1 - lastOccupied);
maxDistance }
return maxDistance;
}