Initial commit — imported from GitHub

This commit is contained in:
Steven (Zen) 2026-08-25 19:14:07 -06:00
commit 169cac6fbc
360 changed files with 24059 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
_site
.sass-cache
.jekyll-cache
.jekyll-metadata
vendor
__pycache__
*.pyc
.idea

25
404.html Normal file
View File

@ -0,0 +1,25 @@
---
permalink: /404.html
layout: default
---
<style type="text/css" media="screen">
.container {
margin: 10px auto;
max-width: 600px;
text-align: center;
}
h1 {
margin: 30px 0;
font-size: 4em;
line-height: 1;
letter-spacing: -1px;
}
</style>
<div class="container">
<h1>404</h1>
<p><strong>Page not found :(</strong></p>
<p>The requested page could not be found.</p>
</div>

33
Gemfile Normal file
View File

@ -0,0 +1,33 @@
source "https://rubygems.org"
# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
#
# bundle exec jekyll serve
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!
gem "jekyll", "~> 4.0.0"
# This is the default theme for new Jekyll sites. You may change this to anything you like.
# gem "minima", "~> 2.5.1"
gem "minima", git: "https://github.com/jekyll/minima"
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
# gem "github-pages", group: :jekyll_plugins
# If you have any plugins, put them here!
group :jekyll_plugins do
gem "jekyll-feed", "~> 0.12"
end
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
# and associated library.
install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
gem "tzinfo", "~> 1.2"
gem "tzinfo-data"
end
# Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1.1", :install_if => Gem.win_platform?
gem "webrick", "~> 1.8"

93
Gemfile.lock Normal file
View File

@ -0,0 +1,93 @@
GIT
remote: https://github.com/jekyll/minima
revision: 2863624b903b17f838d6ce8d2f77900fa9d3c864
specs:
minima (3.0.0.dev)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
colorator (1.1.0)
concurrent-ruby (1.2.2)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
eventmachine (1.2.7)
ffi (1.15.5)
forwardable-extended (2.6.0)
http_parser.rb (0.8.0)
i18n (1.13.0)
concurrent-ruby (~> 1.0)
jekyll (4.0.1)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (>= 0.9.5, < 2)
jekyll-sass-converter (~> 2.0)
jekyll-watch (~> 2.0)
kramdown (~> 2.1)
kramdown-parser-gfm (~> 1.0)
liquid (~> 4.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
rouge (~> 3.0)
safe_yaml (~> 1.0)
terminal-table (~> 1.8)
jekyll-feed (0.17.0)
jekyll (>= 3.7, < 5.0)
jekyll-sass-converter (2.2.0)
sassc (> 2.0.1, < 3.0)
jekyll-seo-tag (2.8.0)
jekyll (>= 3.8, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.4)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (5.0.1)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.5)
rouge (3.30.0)
safe_yaml (1.0.5)
sassc (2.4.0)
ffi (~> 1.9)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
tzinfo (1.2.11)
thread_safe (~> 0.1)
tzinfo-data (1.2023.3)
tzinfo (>= 1.0.0)
unicode-display_width (1.8.0)
wdm (0.1.1)
webrick (1.8.1)
PLATFORMS
ruby
DEPENDENCIES
jekyll (~> 4.0.0)
jekyll-feed (~> 0.12)
minima!
tzinfo (~> 1.2)
tzinfo-data
wdm (~> 0.1.1)
webrick (~> 1.8)
BUNDLED WITH
2.1.4

View File

@ -0,0 +1,21 @@
import sys
arr = [7,1,5,3,6,4]
# arr = [7,6,4,3,1]
# arr = [2,4,1]
def maxProfit(arr):
if not arr or len(arr)==0:
return 0
maxProfit = 0
for i in range(len(arr)):
for j in range(i+1, len(arr)):
if arr[j]-arr[i]>maxProfit:
maxProfit = arr[j]-arr[i]
return maxProfit
print(maxProfit(arr))

View File

@ -0,0 +1,38 @@
import sys
arr = [7,1,5,3,6,4]
arr = [7,6,4,3,1]
arr = [2,4,1]
def maxProfit(arr):
if not arr or len(arr)==0:
return 0
# find lowest pt
globalMin = sys.maxsize
globalMinIndex = -1
for i in range(len(arr)):
if arr[i]<globalMin:
globalMin=arr[i]
globalMinIndex=i
globalMax = -sys.maxsize
globalMaxIndex = -1
# starting from globalMinIndex, find the max value
for i in range(globalMinIndex+1, len(arr)):
if arr[i]>globalMax:
globalMax=arr[i]
globalMaxIndex=i
print(globalMinIndex, globalMaxIndex)
if globalMaxIndex!=-1: # a max was found after global min
return globalMax-globalMin
else:
return 0
print(maxProfit(arr))

View File

@ -0,0 +1,40 @@
arr = [4,5,6,7,2,3]
def findMin(nums):
# 1-elem array
if len(nums)==1:
return nums[0]
left = 0
right = len(nums)-1
# this condition means arr is already sorted, so just return first element
if nums[right] > nums[0]:
return nums[0]
while right>=left:
mid = left + (right-left) // 2
# min found: case 1
if nums[mid] > nums[mid+1]: # 3 4 5 1 2 where 5 is mid
return nums[mid+1]
# min found: case 2
if nums[mid-1] > nums[mid]: # 4 5 1 2 3 where 1 is mid
return nums[mid]
### min not found cases below
# mid is greater than first elem so ignore left half
if nums[mid] > nums[0]:
left = mid+1
# mid is less than first elem, ignore right half
else:
right = mid-1
print(findMin(arr))

View File

@ -0,0 +1,14 @@
arr = [4,5,6,7,2,3]
def findMin(nums):
l, r = 0, len(nums) - 1
while nums[l] > nums[r]:
mid = int((l+r)/2)
if nums[mid] >= nums[l]:
l = mid + 1
else:
r = mid
return nums[l]
print(findMin(arr))

View File

@ -0,0 +1,24 @@
nums = [2,5,3,4,5]
nums = [6,5,3,4,0]
def increasingTriplet(nums):
first = nums[0]
second = float('inf')
third = float('inf')
for n in nums:
if n<first:
first = n
elif n>first and n<second:
second = n
elif n>second and n<third:
third = n
print(first, second, third)
return third!=float('inf')
print(increasingTriplet(nums))

View File

@ -0,0 +1,38 @@
from typing import List
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
map = {}
for num in nums1:
if num not in map:
map[num] = 1
else:
map[num] = map[num] + 1
for k,v in map.items():
print( k, v)
# iter thru num2, if exist in map, minus it
res = []
for num in nums2:
if num in map:
res.append(num)
if map[num]>1:
map[num] = map[num]-1
else:
map.pop(num)
print(res)
# set1 = set(nums1)
# set2 = set(nums2)
# res = set1.intersection(set2)
# return list(res)
nums1 = [1,1,2,2]
nums2 = [2,2]
print( Solution().intersect(nums1, nums2) )

View File

@ -0,0 +1,33 @@
nums1 = [1,2,2,1]
nums2 = [2,2]
def intersect(nums1, nums2):
nums1.sort()
nums2.sort()
i=0
j=0
#1,1,2,2
#2,2
ans = []
# logic is similar to merging
while( i <= len(nums1)-1 and j <= len(nums2)-1 ):
if nums1[i]==nums2[j]:
ans.append(nums1[i])
i+=1
j+=1
elif nums1[i] < nums2[j]:
i+=1
else:
j+=1
return ans
print( intersect(nums1, nums2) )

View File

@ -0,0 +1,37 @@
strs = ["flower","flow","flight"]
strs = ["c","acc","ccc"]
'''
'''
def lcp(strs):
prefix = strs[0]
for i in range(1, len(strs)):
# if substring is found, it will return the first index
# if that element isn't the first char, then chop off
while strs[i].find(prefix) != 0:
# keep chopping off the last character
prefix = prefix[0: len(prefix)-1]
if not prefix: return ""
return prefix
# for s in strs:
# # compare s to longest
# for i in range(len(s)):
# print(s[i], longest[i])
# if s[i]==longest[i]:
# continue
# else:
# longest = longest[:i] # cut off longest to length of common characters of s
# print("longest: ", flower)
# return prefix
print( lcp(strs) )

View File

@ -0,0 +1,55 @@
arr1 = [2, 3, -2,4]
arr2 = [2, 3, 6]
arr3 = [2, -3, 6]
def getMaxProductSubarray(nums):
if not nums: return
left, right, record = 0, 0, -float('inf')
for i in range(len(nums)):
left = (left or 1) * nums[i]
right = (right or 1) * nums[-i-1]
record = max(record, left, right)
return record
def getMaxProductSubarray(arr):
minCurrent = 1
maxCurrent = 1
maxRes = -99999
for i in range(len(arr)):
current = arr[i]
print(i, current, minCurrent, maxCurrent)
if current>0:
maxCurrent = maxCurrent * current
minCurrent = min( minCurrent * current, 1)
elif current==0:
maxCurrent=1
minCurrent=1
else:
x = maxCurrent
maxCurrent = max( minCurrent * current, 1)
minCurrent = x * current
print(i, current, minCurrent, maxCurrent)
if maxRes<maxCurrent:
maxRes = maxCurrent
return maxRes
print(arr1)
print(getMaxProductSubarray(arr1))
print()
print(arr2)
print(getMaxProductSubarray(arr2))
print()
print(arr3)
print(getMaxProductSubarray(arr3))
print()

View File

@ -0,0 +1,21 @@
arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
def maxSubarray(arr):
if not arr:
return None
for i in range(len(arr)):
if i==0:
continue
else:
arr[i] = max(arr[i], arr[i-1] + arr[i]) # max of "start with this elem" or "continue the existing subarray"
return max(arr)
print(maxSubarray(arr))

View File

@ -0,0 +1,46 @@
'''
Given an array of integers and a number k, find maximum sum of a subarray of size k.
11:40
https://medium.com/hackernoon/14-patterns-to-ace-any-coding-interview-question-c5bb3357f6ed#6698
https://www.geeksforgeeks.org/find-maximum-minimum-sum-subarray-size-k/
'''
def main():
# arr = [1,2,3,4,2]
# k = 2
arr = [1, 4, 2, 10, 23, 3, 1, 0, 20]
k = 4
maxSum = 0
for i in range(0, len(arr)-k+1 ):
sum = 0
for j in range(0, k):
# set j to beginning of window
j=i
sum = sum + arr[j]
i+=1
print sum
if sum > maxSum:
maxSum = sum
print 'max sum is ' + str(maxSum)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,18 @@
nums = [3,0,1]
n = len(nums)
# sum total if number wasn't missing
total = 0
for i in range(0, n+1):
total = total + i
# sum actual numbers in array
arr_total = 0
for i in range(0, n):
arr_total = arr_total + nums[i]
print(total)
print(arr_total)
print(total-arr_total)

View File

@ -0,0 +1,53 @@
'''
https://leetcode.com/problems/pascals-triangle/
'''
def main():
def generate(numRows):
triangle = []
if numRows==0:
return []
# add first row
triangle.append([1])
# add other rows
for i in range(1, numRows):
curr_row = i
# append placeholders to each row
row = []
for i in range(0, curr_row+1):
if i==0:
row.append(1)
elif i==curr_row:
row.append(1)
else:
# print triangle[curr_row-1][i]
# print triangle[curr_row-1][i-1]
# row.append(None)
row.append( triangle[curr_row-1][i] + triangle[curr_row-1][i-1] )
triangle.append(row)
return triangle
print generate(5)
if __name__ == "__main__":
main()

29
_code/arrays/plusOne.py Normal file
View File

@ -0,0 +1,29 @@
digits = [9]
def plusOne(digits):
ptr = len(digits)-1
carry = 1 # just set carry=1 to do get into the loop
while carry==1:
# edge case when carry=1 and ptr goes left off the edge (ie: '9')
if ptr<0:
digits.insert(0, 1)
return digits
# normal case: just add one to last digit
if digits[ptr]>=0 and digits[ptr]<9:
digits[ptr] = digits[ptr]+1
carry=0
return digits
# edge case, set carry and move left
elif digits[ptr]==9:
digits[ptr] = 0
carry = 1
ptr-=1
return digits
print( plusOne(digits) )

View File

@ -0,0 +1,36 @@
arr = [0,1,0,1,1,0,0,1]
N=1000000000
# N=7
def prisonAfterNDays(arr, N):
def computeNext(arr):
arr2 = [0]*len(arr)
for i in range(1, len(arr)-1):
# not xor the middle
arr2[i] = int(not arr[i-1] ^ arr[i+1])
# make ends zero
arr2[0], arr2[len(arr)-1] = 0,0
# copy arr2 to arr
return arr2.copy()
seen = {str(arr): N}
while N:
seen.setdefault(str(arr), N)
N -= 1
# arr = [0] + [arr[i - 1] ^ arr[i + 1] ^ 1 for i in range(1, 7)] + [0]
arr = computeNext(arr)
if str(arr) in seen:
N %= seen[str(arr)] - N
return arr
print( prisonAfterNDays(arr, N) )

View File

@ -0,0 +1,26 @@
arr = [1,2,3,4,5,6,7]
arr = [-1]
arr = [1,2]
def rotate(nums, k):
if not nums: return
if len(nums) == 1: return
def reverse(nums, start, end):
while start < end:
tmp = nums[start]
nums[start] = nums[end]
nums[end] = tmp
start += 1
end -= 1
reverse(nums, 0, len(nums) - 1)
reverse(nums, 0, k - 1)
reverse(nums, k, len(nums) - 1)
rotate(arr, 3)
print(arr)

View File

@ -0,0 +1,19 @@
nums = [4,5,6,7,2,3]
target = 1
def search(nums, target):
left = 0
right = len(nums)-1
# this loop gets left to the smallest element
while left<right:
mid = (left + right) // 2
if nums[mid] > nums[right]:
left = mid+1
else:
right = mid
print( search(nums, target) )

View File

@ -0,0 +1,36 @@
def main():
arr = [-3,-2,-1,0,1,2,3]
# move ptrs to middle section, j moves forward, i moves backwards
j = 0
while arr[j]<0:
j+=1
i=j-1
# create new array to store results
ans = []
while i>=0 and j<len(arr):
print arr[i]
print arr[j]
print ''
if arr[i]**2 < arr[j]**2:
ans.append( arr[i]**2 )
i-=1
else:
ans.append( arr[j]**2 )
j+=1
print ans
if __name__ == "__main__":
main()

45
_code/arrays/threeSum.py Normal file
View File

@ -0,0 +1,45 @@
# ans = []
# for i in range(len(nums)):
# for j in range(i, len(nums)):
# for k in range(j, len(nums)):
# if nums[i] + nums[j] + nums[k] == 0:
# ans.append([nums[i], nums[j], nums[k]])
# nums = [-1, 0, 1, 2, -1, -4]
nums = [0,0,0,0]
def threeSum(nums):
nums.sort()
output = []
print(nums)
index = 0
while index<len(nums):
fixed = nums[index] # -1
target = fixed*-1 # want to find 1 in rest of array
l,r = index+1, len(nums)-1
while l<r:
if nums[index] + nums[l] + nums[r] == 0:
output.append( [nums[index], nums[l], nums[r]] )
l+=1
r-=1
index+=1
return output
print(threeSum(nums))

View File

@ -0,0 +1,34 @@
costs = [
[10,20],
[30,200],
[400,50],
[30,20]
]
def minCosts(costs):
n = len(costs)//2
# calculate the difference between city A and city B for each person
delta = [(a - b) for a, b in costs]
print( "delta: ", delta )
# get the ordered difference
ordered_delta = sorted((value, i) for (i, value) in enumerate(delta))
print( "ordered delta:", ordered_delta )
minimum_cost = 0
# for the n smallest cost_A - cost_B, it costs a lot to fly to B,
# so we send them to city A
print( "ordered_delta[:n] ", ordered_delta[:n] )
for value, i in ordered_delta[:n]:
minimum_cost += costs[i][0]
# for the n greatest cost_A - cost_B, it costs a lot to fly to A,
# so we send them to city B
for value, i in ordered_delta[n:]:
minimum_cost += costs[i][1]
return minimum_cost
print( minCosts(costs) )

20
_code/arrays/twoSum.py Normal file
View File

@ -0,0 +1,20 @@
nums = [2, 7, 11, 15]
target = 26
def twoSum(nums, target):
length = len(nums)
for i in range(0, length):
for j in range(i+1, length):
if nums[i] + nums[j] == target:
return (i, j)
break
j=j+1
res = twoSum(nums, target)
print res

View File

@ -0,0 +1,17 @@
nums = [2, 7, 11, 15]
target = 9
def twoSum(nums, target):
seen = {}
for i, v in enumerate(nums):
remaining = target - v
if remaining in seen:
return [seen[remaining], i]
seen[v] = i
return []
res = twoSum(nums, target)
print (res)

View File

@ -0,0 +1,26 @@
height = [1,8,6,2,5,4,8,3,7]
def maxArea(height):
left = 0
right = len(height)-1
maxArea = 0
while left<right:
minHeight = min( height[left], height[right] )
distance = right-left
maxArea = max( maxArea, minHeight*distance )
# move shorter one inward
if height[left]<height[right]:
left+=1
else:
right-=1
return maxArea
print(maxArea(height))

View File

@ -0,0 +1,34 @@
import sys
sys.setrecursionlimit(10)
nums = [1,2,3]
def permute(nums):
output = []
def backtrack(currentList):
print(currentList)
# base case
if len(currentList)==len(nums):
output.append(currentList.copy())
# imagine you're at [1] (your currentList) and you want to append 1,2,3 to your child branches
# so they become 11, 12, 13
for i in range(0, len(nums)):
if nums[i] in currentList:
continue
currentList.append(nums[i])
backtrack(currentList)
currentList.pop()
backtrack([])
return output
print( permute(nums) )

View File

@ -0,0 +1,22 @@
candidates = [2,3,6,7]
target = 7
def combinationSum(candidates, target):
def backtrack(currentList, nums, start):
if sum(currentList)==target:
allValidCombos.append( currentList.copy() )
return
if sum(currentList) > target: # optimization
return
for i in range(start, len(nums)):
backtrack(currentList + [nums[i]], nums, i)
# currentList.append( nums[i] )
# backtrack( currentList, nums, start)
allValidCombos = []
backtrack([], candidates, 0 )
return allValidCombos
print( combinationSum(candidates, target) )

View File

@ -0,0 +1,25 @@
n=3
def generateParenthesis(n):
def backtrack(outputList, currentString, open, close, n):
if len(currentString)==2*n:
outputList.append(currentString)
print("output " + currentString)
return
print( currentString )
if open < n:
backtrack( outputList, currentString+"(", open+1, close, n )
if close < open:
backtrack( outputList, currentString+")", open, close+1, n)
outputList = []
backtrack( outputList, "", 0, 0, n)
return outputList
print( generateParenthesis(n) )

View File

@ -0,0 +1,47 @@
# nums = [10,20,30]
nums = [1,1,2]
def permute1(nums):
def backtrack(currentList, allPermutations, nums):
if len(currentList)==len(nums):
allPermutations.append(currentList[:]) # or currentList.copy() because Python passes by reference
else:
for i in range(0, len(nums)):
if nums[i] in currentList:
continue
currentList.append(nums[i])
backtrack( currentList, allPermutations, nums )
currentList.remove(currentList[-1]) # currentList.pop() also does the same thing
allPermutations = []
backtrack([], allPermutations, nums)
return allPermutations
def permute2(nums):
def backtrack(currentList, allPermutations, nums):
if len(currentList)==len(nums):
allPermutations.append(currentList.copy())
else:
for i in range(len(nums)):
currentList.append(nums[i])
print(currentList)
backtrack(currentList, allPermutations, nums)
currentList.pop()
print(currentList)
allPermutations = []
backtrack([], allPermutations, nums)
return allPermutations
# print(permute1(nums))
# print()
print(permute2(nums))

View File

@ -0,0 +1,130 @@
nums = [1,2,3]
# def subsets(nums):
# def backtrack(first = 0, curr = []):
# # if the combination is done
# if len(curr) == k:
# output.append(curr[:])
# for i in range(first, n):
# # add nums[i] into the current combination
# curr.append(nums[i])
# # use next integers to complete the combination
# backtrack(i + 1, curr)
# # backtrack
# curr.pop()
# output = []
# n = len(nums)
# for k in range(n + 1):
# backtrack()
# return output
def subsets(nums):
subsets = []
def generateSubsets(index, nums, current, subsets):
subsets.append(current[:])
for i in range(index, len(nums)):
current.append(nums[i])
generateSubsets(i + 1, nums, current, subsets)
current.remove(current[-1])
generateSubsets(0, nums, [], subsets)
return subsets
def subsets2(nums):
def backtrack(startIndex, currentSubset, allSubsets, nums):
allSubsets.append(currentSubset[:])
for i in range(startIndex, len(nums)):
currentSubset.append(nums[i])
print(currentSubset)
backtrack( i+1, currentSubset, allSubsets, nums)
currentSubset.remove( currentSubset[-1] )
print(currentSubset)
allSubsets = []
backtrack( 0, [], allSubsets, nums )
return allSubsets
def subsets3(nums):
def backtrack(currentSubset, allSubsets, nums, index):
allSubsets.append( currentSubset.copy() )
for i in range(index, len(nums)):
currentSubset.append(nums[i])
print(currentSubset)
backtrack( currentSubset, allSubsets, nums, i+1 )
currentSubset.pop()
print(currentSubset)
ans = []
backtrack([], ans, nums, 0)
return ans
'''
recursion without backtracking from timonthy chang
https://www.youtube.com/watch?v=Mi_C_CMW7vQ
'''
def subsets4(nums):
output = []
def helper(start, currentSubset, output):
# output += [tmp]
output.append(currentSubset)
for i in range(start, len(nums)):
print( (i+1, currentSubset+[nums[i]]) )
helper( i+1, currentSubset+[nums[i]], output )
helper(0, [], output)
return output
def subsets5(nums):
def helper(start, currentSubset, allSubsets):
output.append( currentSubset.copy() )
for i in range(start, len(nums) ):
currentSubset.append( nums[i] )
print(i+1, currentSubset)
helper(i+1, currentSubset, output)
currentSubset.pop()
output = []
helper(0, [], output)
return output
'''
https://medium.com/leetcode-patterns/leetcode-pattern-3-backtracking-5d9e5a03dc26
'''
# print(subsets2(nums))
# print()
# print(subsets3(nums))
print(subsets4(nums))
print(subsets5(nums))

69
_code/bfs/bfs.py Normal file
View File

@ -0,0 +1,69 @@
class TreeNode:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def levelOrder(root):
q = [root]
ans = []
while q:
level_size = len(q)
level = []
for i in range(level_size):
curr = q.pop(0)
level.append(curr.val)
if curr.left:
q.append(curr.left)
if curr.right:
q.append(curr.right)
if level:
ans.append(level)
return ans[::-1]
# q = [root]
# ans = []
# while q:
# level_size = len(q)
# level = []
# for _ in range(level_size):
# curr = q.pop(0)
# level.append(curr.val)
# if curr.left:
# q.append(curr.left)
# if curr.right:
# q.append(curr.right)
# ans.append(level)
# return ans[::-1]
root = TreeNode(3)
root.left = TreeNode(9)
root.right = TreeNode(20)
# root.left.left = TreeNode(4)
# root.left.right = TreeNode(5)
root.right.left = TreeNode(15)
root.right.right = TreeNode(7)
# root.right.right.right = TreeNode(8)
print( levelOrder(root) )

View File

@ -0,0 +1,21 @@
n=5
def arrangeCoins(n):
l = 1
h = n
while l<=h:
mid = l + (h-l)//2
temp = int(mid*(mid+1)/2)
print(l, mid, h, temp, [ (x*(x+1)//2) for x in range(l,h)])
if temp == n:
return mid
if temp < n:
l = mid + 1
else:
h = mid - 1
return h
print(arrangeCoins(n))

View File

@ -0,0 +1,32 @@
# arr = [1,2,3,4,5,6,7,8,9,10]
arr = [-1,0,3,5,9,12]
def binSearch(low, high, arr, target):
while low<=high:
print(low, high, arr, target)
mid = int((low+high)/2)
# mid = low+high//2
if arr[mid]==target:
return mid
# if target is greater, ignore left half
elif arr[mid]<target:
low = mid+1
# if target is less, ignore right half
else:
high = mid-1
return -1
res = binSearch(0, len(arr), arr, 13)
print(res)

View File

@ -0,0 +1,28 @@
arr = [1,2,3,4,5]
def binarySearch(left, right, arr, target):
print(left, right, arr, target)
print( right, left, right<=left )
while left<=right:
print(left, right, arr, target)
mid = int((left+right)/2)
# mid = left+right//2
if arr[mid]==target:
return mid
elif target>arr[mid]:
left = mid+1
else:
right = mid-1
return -1
print(binarySearch(0, len(arr)-1, arr, 4))

View File

@ -0,0 +1,41 @@
def searchInsert(nums, target):
left = 0
right = len(nums)-1
while left<=right:
mid = (left+right)//2
if target==nums[mid]:
return mid
# # left and right beside each other
# elif right-left<=1:
# # and target is inbetween (ie: [4,6], tar=5)
# if target>=nums[left] and target<=nums[right]:
# return left+1
# # target is outside of array (to the right)
# elif target>nums[right]:
# return right+1
# # target is outside of array (to the left)
# elif target<nums[left]:
# return left
elif target>nums[mid]:
left = mid+1
elif target<nums[mid]:
right = mid-1
return left
print( searchInsert( [1,3,5,6] , 5) ) # 2
print( searchInsert( [1,3,4,6] , 5) ) # 3
print( searchInsert( [1,2] , 3) ) # 2
print( searchInsert( [1,2] , 0) ) # 0
print( searchInsert( [1,3] , 2) ) # 1

View File

@ -0,0 +1,35 @@
# mat = [
# [1,2,3,4],
# [5,6,7,8],
# [9,10,11,12]
# ]
mat = [[1,3,5,7],[10,11,16,20],[23,30,34,50]]
mat = [[1,3,5,7],[10,11,16,20],[23,30,34,50]]
def searchMatrix(mat, target):
rows = len(mat)
cols = len(mat[0])
start = 0
end = rows * cols - 1
while start<=end:
mid = (start+end)//2 # this would be the mid if it was a 1d array
row = mid // cols
col = mid % cols
val=mat[row][col]
if val==target:
return True
elif val<target:
start=mid+1
else:
end=mid-1
return False
print(searchMatrix(mat, 13))

View File

@ -0,0 +1,14 @@
# print( bin(4).replace("0b", "") )
a = "1010"
b = "1011"
decA = int(a, 2)
decB = int(b, 2)
print(decA, decB, decA+decB, bin(decA+decB))
res = bin( decA + decB ).replace("0b", "")
print(res)

View File

@ -0,0 +1,38 @@
class Node:
def __init__(self, val):
self.val = val
self.next = None
def getCount(head):
count = 0
while head:
count = count + 1
head = head.next
return count
def binToInt(head):
sum = 0
count = getCount(head) - 1
while head:
sum = sum + ( (2**count) * head.val )
count = count-1
head = head.next
return sum
head = Node(1)
head.next = Node(0)
head.next.next = Node(1)
print( getCount(head) )
print( binToInt(head) )

View File

@ -0,0 +1,44 @@
'''
https://leetcode.com/problems/counting-bits/
Problem:
Given num, return array which contains numOnes
Ie, input = 2, return [0,1,1]
Do it in O(n) time, and not O(n*numBits)
Solution: dynamic programming (build table bottom up)
d[i] = d[i//2] + (i%2)
ex:
d[3] = d[3//2] + 3%2
= d[1] + 1
= 2
d[6] = d[6//2] + 6%2
= d[3] + 0
= 2 + 0
= 2
d[7] = d[7//2] + 7%2
= d[3] + 1
= 2 + 1 = 3
https://leetcode.com/problems/counting-bits/discuss/626777/Easy-DP-Explanation-%3A-Python-Solution
'''
def countOnes(num):
if num==0: return [0]
if num==1: return [0,1]
dp=[0,1]
for i in range(2, num+1):
# dp[i] = dp[i//2] + (i%2)
dp.append( dp[i//2] + (i%2) )
return dp
print(countOnes(2))

View File

@ -0,0 +1,14 @@
x = 1
y = 3
tmp = x ^ y
count=0
while tmp>0:
if tmp&1==1:
count+=1
tmp>>=1
print( count )

View File

@ -0,0 +1,12 @@
def hammingWeight(self, n: int) -> int:
count = 0
while n>0:
if n&1==1:
count+=1
n>>=1
return count

View File

@ -0,0 +1,13 @@
nums = [3,0,1]
n = len(nums)
# xor index with value
xor = 0
for i, num in enumerate(nums):
xor ^= i^num
# xor with length gives you missing num
missing = xor^n
print(missing)

View File

@ -0,0 +1,26 @@
def reverseBits(str):
n = int(str)
rev = 0
# tranverse bits from right to left
while n>0:
rev = rev << 1
# if current bit is 1
if (n&1==1):
rev = rev ^ 1
n = n >> 1
return rev
print reverseBits("4567")

View File

@ -0,0 +1,19 @@
nums = [1,2,1,3,2,5]
def singleNumber(nums):
xor = 0
for n in nums:
xor ^= n
# xor = num1 ^ num2
firstbit = xor & (xor-1) ^ xor
num1 = 0
for n in nums:
if n & firstbit:
num1 ^= n
return [num1, num1^xor]
print( singleNumber(nums) )

View File

@ -0,0 +1,26 @@
nums = [2,2,3,2]
def singleNumber(nums):
single = 0
for i in range(32):
count = 0
for num in nums:
# if num & (1<<i) == (1<<i): count +=1
if num & (1<<i) == (1<<i): count += 1
single |= (count%3) << 1
return single if single < (1<<31) else sing
le - (1<<32)
# def singleNumber(nums):
# single = 0
# for i in range(32):
# count = 0
# for num in nums:
# if num & (1<<i) == (1<<i): count += 1
# single |= (count%3) << i
# return single if single < (1<<31) else single - (1<<32)
print(singleNumber(nums))

View File

@ -0,0 +1,39 @@
class TreeNode:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def zigzagLevelOrder(root):
output = []
def dfs(node, level, output):
if not node:
return
if len(output) <= level:
output += [[]]
dfs(node.left, level+1, output)
dfs(node.right, level+1, output)
if level%2==0:
output[level].append(node.val)
else:
output[level].insert(0, node.val)
dfs(root, 0, output)
return output
root = TreeNode(3)
root.left = TreeNode(9)
root.right = TreeNode(20)
root.right.left = TreeNode(15)
root.right.right = TreeNode(7)
print( zigzagLevelOrder(root) )

View File

@ -0,0 +1,36 @@
coins = [1,2,5]
amount = 11
def coinChange(coins, amount):
if not amount: return 0
min_coins = [0] + [float('inf')] * amount
for c in coins:
for i in range(c, amount + 1):
print(c, i, min_coins, min_coins[i], min_coins[i-c])
min_coins[i] = min(min_coins[i], min_coins[i - c] + 1) # current val is min of current val or current val - coin + 1
print(c, i, min_coins, min_coins[i], min_coins[i-c])
print()
return min_coins[-1] if min_coins[-1] != float('inf') else -1
def coinChange2(coins, amount):
dp = [0] + [float('inf')]*amount
for i in range(1, amount+1):
for c in coins:
dp[i] = min( dp[i], dp[i-c]+1)
print(dp)
return dp[-1] if dp[-1]!=float('inf') else -1
print(coinChange2(coins, amount))

View File

@ -0,0 +1,20 @@
amount = 5
coins = [1,2,5]
def change(amount, coins):
dp = [[1]+[0]*amount for _ in range(len(coins)+1)]
for i in range(1, len(coins)+1):
for j in range(1, amount+1):
if coins[i-1] <= j:
dp[i][j] = dp[i-1][j] + dp[i][j-coins[i-1]]
else:
dp[i][j] = dp[i-1][j]
print(dp)
return dp[len(coins)][amount] # or dp[-1][-1]
print( change( amount, coins ) )

View File

@ -0,0 +1,23 @@
nums = [1,2,3,1]
# [1,2,3,1]
# [1,2,4,4]
def rob(nums):
if not nums: return 0
dp = [1] * len(nums)
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in range(2, len(nums)):
# dp.append( max( nums[i] + dp[i-2], dp[i-1] ) )
dp[i] = max( nums[i] + dp[i-2], dp[i-1] )
print(dp)
return dp[-1]
print(rob(nums))

View File

@ -0,0 +1,31 @@
nums = [1,2,3,1]
nums = [1]
def rob(nums):
# handle edge cases
if not nums: return 0
if len(nums)==1: return nums[0]
if len(nums)==2: return max(nums[0], nums[1])
def robHelper(nums):
dp = [1] * len(nums)
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in range(2, len(nums)):
dp[i] = max( nums[i] + dp[i-2], dp[i-1] )
print(dp)
return dp[-1]
excludeFirst = nums[1:]
excludeLast = nums[:-1]
return max( robHelper(excludeFirst), robHelper(excludeLast) )
print(rob(nums))

View File

@ -0,0 +1,31 @@
str1 = "AABA"
str2 = "AZB"
def lcs(text1, text2):
n= len(text1)
m= len(text2)
# creates an [m+1][n+1] matrix, filled with zeros
table=[[0]*(n+1) for _ in range(m+1)]
for i in range(1, m+1):
for j in range (1, n+1):
# first char is the same, so add 1 to count
if text2[i-1]==text1[j-1]:
table[i][j]= 1+table[i-1][j-1]
# first char is different, so break into subproblems and take the max
else:
table[i][j]=max(table[i-1][j],table[i][j-1])
print( [0]*(n+1) )
print( range(m+1) )
print( table )
print( max(table) ) # this get the last element at the end of the list
return max(max(table)) # this gets the last element at the bottom right corner (last element of both lists)
print( lcs(str1, str2))

View File

@ -0,0 +1,63 @@
12
1 4 9
build perfect squares up to n
12-9=3
3-1=2
2-1=1
12=9+1+1+1 -> 4
12=4+4+4 -> 3
1 -> 1 (1)
2 -> 2 (1+1)
3 -> 3 (1+1+1)
4 -> 1 (4)
5 -> 2 (4+1)
6 -> 3 (4+1+1)
7 -> 4 4+1+1+1
8 -> 2 4+4
f(1) = 1
f(2) = f(1) + f(1) = 1+1=2
f(7) = f(4) + f(3) = 1+3=4
f(8) = f(4) + f(4) = 1+1=2
f(12) = f(8) + f(4) = 2+1=3
identify subproblems?
https://leetcode.com/problems/perfect-squares/discuss/696436/Python-Simple-DP-Solution
n=7
square_sums = [0,1,4]
dp = [0, inf, inf, inf, inf, inf, inf, inf]
0 1 2 3 4 5 6 7
dp = [0, 1, 2, 3, 1, 2, 3, 4]
dp = [0, 1, inf, inf, 1, inf, inf, inf]
i: 1->n
iter all squares
min( dp[i], dp[i-square] )
f(1)=1
f(2)=2
f(12)=
these are the candidates

View File

@ -0,0 +1,13 @@
import math
n = 7
def numSquares(n):
squares = [i**2 for i in range(0, int(math.sqrt(n))+1) ]
dp = [float(inf)] * n
print(squares)
print(dp)
print( numSquares(n) )

View File

@ -0,0 +1,33 @@
import collections
n = 3
edges = [[0,1,100],[1,2,200],[0,2,500]]
src = 0
dst = 2
k = 1
def findCheapestPrice(n, flights, src, dst, K):
if src == dst: return 0
d, seen = collections.defaultdict(list), collections.defaultdict(lambda: float('inf'))
for u, v, p in flights:
d[u] += [(v, p)]
q = [(src, -1, 0)]
while q:
pos, k, cost = q.pop(0)
if pos == dst or k == K: continue
for nei, p in d[pos]:
if cost + p >= seen[nei]:
continue
else:
seen[nei] = cost+p
q += [(nei, k+1, cost+p)]
return seen[dst] if seen[dst] < float('inf') else -1
print( findCheapestPrice(n, edges, src, dst, k) )

View File

@ -0,0 +1,52 @@
from collections import deque
'''
https://www.youtube.com/watch?v=Jbb9qNIAyg0
'''
import collections
n = 3
flights = [[0,1,100],[1,2,200],[0,2,500]]
src = 0
dest = 2
k = 1
def findCheapestPrice(n, flights, src, dest, K):
# d = collections.defaultdict(list)
# seen = collections.defaultdict(lambda: float('inf'))
adj = [[] for _ in range(n)]
output = [float('inf') for _ in range(n)]
output[src] = 0
# add to adj list where key is src, and value is destination+cost
for u, v, w in flights:
adj[u] += [(v, w)]
graph = deque()
graph.append((src, -1)) # where -1 is the number of stops
while graph:
u, stop = graph.popleft()
if stop >= K:
continue
for v, w in adj[u]:
output[v] = output[u]+w
graph.append((v,stop+1))
if output[dest] == float('inf'):
return -1
else:
return output[dest]
print( findCheapestPrice(n, flights, src, dest, k) )

View File

@ -0,0 +1,44 @@
import heapq
from collections import deque
from collections import defaultdict
'''
https://www.youtube.com/watch?v=Jbb9qNIAyg0
'''
n = 3
flights = [[0,1,100],[1,2,200],[0,2,500]]
src = 0
dest = 2
k = 1
def findCheapestPrice(n, flights, src, dest, K):
output = [float("inf")] * n
output[src] = 0
graph = defaultdict(list)
heap = [(src, -1)] # dest, costs
# add to adj hash table
for u, v, w in flights:
graph[u].append((v,w))
while heap:
v, w = heapq.heappop(heap)
for v, w in graph[v]:
output[v] = output[u]+w
heapq.heappush(heap, (v, output[u]+w))
print( output )
print( findCheapestPrice(n, flights, src, dest, k) )

View File

@ -0,0 +1,25 @@
from collections import deque
# graph as adjacency lists (dictionary of lists)
graph = {}
graph["you"] = ["alice", "bob", "claire"]
graph["bob"] = ["anuj", "peggy"]
graph["alice"] = ["peggy"]
graph["claire"] = ["thom", "jonny"]
graph["anuj"] = []
graph["peggy"] = []
graph["thom"] = []
graph["jonny"] = []
print(graph)
# create queue
search_queue = deque()
search_queue += graph["you"]
while search_queue:
person = search_queue.popleft()
if p

View File

@ -0,0 +1,44 @@
# dijkstra needs 3 hashtables and a list to keep track of processed nodes
graph = {}
costs = {}
parents = {}
processed = []
# graph: a hashtable of more hash tables to store edges and weights
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2
graph["a"] = {}
graph["a"]["fin"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {}
# costs: a hashtable to store costs of each node
infinity = float("inf")
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity
# parents hashtable
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None
print( graph )
print( costs )
print( parents )

View File

@ -0,0 +1,37 @@
import heapq
from collections import deque
from collections import defaultdict
times = [[2,1,1],[2,3,1],[3,4,1]]
N = 4
K = 2
def networkDelayTime(times, N, K):
elapsedTime = [0] + [float("inf")] * N
graph = defaultdict(list)
heap = [(0, K)]
# add to adj hash table, where group
for u, v, w in times:
graph[u].append((v, w))
while heap:
# pop off heap/queue
time, node = heapq.heappop(heap)
if time < elapsedTime[node]:
# process (add to elapsed time array)
elapsedTime[node] = time
# add neighbours, include weight
for v, w in graph[node]:
heapq.heappush(heap, (time + w, v))
mx = max(elapsedTime)
return mx if mx < float("inf") else -1
print( networkDelayTime(times, N, K) )

View File

@ -0,0 +1,23 @@
# tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
def findTicketIndForStartCity(startCity):
for ticketInd, cities in enumerate(tickets):
if cities[0]==startCity:
return ticketInd
tickets.sort(key=lambda x: x[1])
output = ['JFK']
for i in range(0, len(tickets)):
currTicketIndex = findTicketIndForStartCity( output[-1] )
nextCity = tickets[currTicketIndex][1]
output.append(nextCity)
print(output)

View File

@ -0,0 +1,30 @@
tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
# tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
def findTicketIndForStartCity(startCity):
graph = {}
tickets.sort(key=lambda x: x[1])
# add all to graph hashmap
for u, v in tickets:
if u in graph:
graph[u].append(v)
else:
graph[u] = [v]
# put jfk on stack
itinerary, stack = [], [("JFK")]
while stack:
curr = stack[-1]
if curr in graph and len(graph[curr]) > 0:
stack.append(graph[curr].pop(0))
else:
itinerary.append(stack.pop())
return itinerary[::-1]
print( findTicketIndForStartCity(tickets) )

15
_code/greedy/jumpGame.py Normal file
View File

@ -0,0 +1,15 @@
arr = [2,3,1,1,4]
def canJump(nums) -> bool:
lastGoodPos = len(nums) - 1
for i in reversed(range(len(nums))):
print(i, nums[i], lastGoodPos, i + nums[i] >= lastGoodPos)
if i + nums[i] >= lastGoodPos:
lastGoodPos = i
return lastGoodPos == 0
canJump(arr)

View File

@ -0,0 +1,22 @@
people = [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
# turn to [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
def reconstructQueue(people):
print(people)
# sort ppl by decending height first and k second
people.sort(key=lambda x: (-x[0], x[1]))
print(people)
ans = []
for person, num in people:
if num >= len(ans):
ans.append([person, num])
else:
ans.insert(num, [person, num])
return ans
print( reconstructQueue(people) )

View File

@ -0,0 +1,20 @@
def normalize(word):
# map[char] -> [mapped integer]
myMap = {}
count=0
normalized=""
for c in word:
if c not in myMap:
myMap[c] = count
count+=1
normalized += str(myMap[c])
else:
normalized += str(myMap[c])
return normalized
print( normalize("aa") )

View File

@ -0,0 +1,21 @@
import re
def LongestWord(sen):
# code goes here
tokens = sen.split(" ")
maxWord = ""
maxLength = 0
for token in tokens:
token = re.sub('[^a-zA-Z]','', token)
if len(token) > maxLength:
maxLength = len(token)
maxWord = token
return maxWord
# keep this function call here
print(LongestWord(input()))

14
_code/heap/heaptest.py Normal file
View File

@ -0,0 +1,14 @@
import heapq
li = [5, 7, 9, 1, 3]
heapq.heapify(li)
# printing created heap
print ("The created heap is : ",end="")
print (list(li))
heapq.heappush(li,4)
print ("The modified heap after push is : ",end="")
print (list(li))

View File

@ -0,0 +1,29 @@
import heapq
stones = [2,7,4,1,8,1]
def lastStoneWeight(stones):
while len(stones)>=2:
# negate values for max heap
stones = list(map(lambda x: -x if x>0 else x, stones))
# stones = [-x for x in stones if x>0 else x]
print(stones)
# get top 2 heaviest stones
heapq.heapify(stones)
print(stones)
heavy1 = heapq.heappop(stones)
heavy2 = heapq.heappop(stones)
# smash the heaviest stones
diff = abs(heavy1-heavy2)
heapq.heappush(stones, diff)
print(stones)
print(stones)
return stones[0]
print(lastStoneWeight(stones))

View File

@ -0,0 +1,66 @@
'''
https://leetcode.com/problems/top-k-frequent-elements/solution/
https://hg.python.org/cpython/file/2.7/Lib/heapq.py#l16
https://www.youtube.com/watch?v=Gj4-8sRi7W0
'''
from collections import Counter
import heapq
nums = [1,1,1,2,2,3]
def topKFrequent1(nums, k):
count = Counter(nums)
return heapq.nlargest(k, count.keys(), key=count.get)
def topKFrequent2(nums, k):
c = Counter(nums) # {1: 3, 2: 2, 3: 1}
c = [(-v,k) for k,v in c.items()] # (v,k) [(3, 1), (2, 2), (1, 3)]
# (-v,k) [(-3, 1), (-2, 2), (-1, 3)]
heapq.heapify(c)
output = []
for i in range(k):
item = heapq.heappop(c)
output.append(item[1])
return output
print(topKFrequent2(nums, 2))
____________
{% highlight python %}
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
minHeap=[]
c = Counter(nums)
for n in c.values():
heapq.heappush(minHeap, n)
if len(minHeap)>k:
heapq.heappop(minHeap)
out = []
for k,v in c.items():
if v in minHeap:
out.append(k)
return out
{% endhighlight %}

View File

@ -0,0 +1,126 @@
class DLLNode:
def __init__(self, key, val):
self.key = key
self.val = val
self.next = None
self.prev = None
class LruCache:
def __init__(self, capacity):
# hashtable for fast lookup
self.hashmap = {}
self.capacity = capacity
self.head = None # most recently used item
self.tail = None # least recently used item
def get(self, key):
## TODO
return hashmap.get(key)
'''
put will need to put elements into
'''
def put(self, key, val):
# if capacity is reached, evict last elem
# if len(self.hashmap)==self.capacity:
# print "capacity reached"
# lastNode = self.tail
# self.tail = lastNode.prev
# lastNode.prev = None
# key exists in hash table
if key in self.hashmap:
# update node's value
currentNode = self.hashmap[key]
currentNode.val = val
# if current node is not head
if not currentNode == self.head:
# remove yourself from list
if currentNode.prev:
currentNode.prev.next = currentNode.next
if currentNode.next:
currentNode.next.prev = currentNode.prev
# add to beginning of list
currentNode.next = self.head
self.head = currentNode # reassign head node
# if current node is tail node
if currentNode == self.tail:
self.tail = currentNode.prev
currentNode.prev = None
# not in hash table
else:
# put it at the front of the list
newNode = DLLNode(key, val)
if not self.head:
self.head = newNode
self.tail = newNode
else:
newNode.next = self.head
self.head.prev = newNode
self.head = newNode # reassign head node
# add node to hash table
self.hashmap[key] = newNode
def show(self):
# print hashmap
print( self.hashmap )
print ("head: " + str(self.head.val))
print ("tail: " + str(self.tail.val))
# iterate doubly linked list
node = self.head
while node:
print( node.val )
node = node.next
print("")
cache = LruCache(3)
cache.put(1,10)
cache.put(2,20)
cache.put(3,30)
cache.show()
cache.put(2, 200) # move elem to head
cache.show()
cache.put(1, 100) # move end elem to beginning
cache.show()
cache.put(1, 1000) # move start elem to beginning (breaks)
cache.show()
cache.put(4, 40)
cache.show() # test new eviction logic

View File

@ -0,0 +1,54 @@
class MinStack:
def __init__(self):
self.s1 = []
self.s2 = []
def push(self, num):
self.s1.append( num )
if len(self.s2)==0 or num < self.s2[-1]:
self.s2.append( num )
else:
self.s2.append( self.s2[-1] )
def pop(self):
self.s2.pop()
return self.s1.pop()
def show(self):
print(self.s1)
print(self.s2)
print("Min: ", self.s2[-1] )
print('')
def main():
minStack = MinStack()
minStack.push(3)
minStack.show()
minStack.push(1)
minStack.show()
minStack.push(2)
minStack.show()
minStack.pop()
minStack.show()
minStack.pop()
minStack.show()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,40 @@
'''
LL56: Merge Sorted Intervals
'''
# nonSorted = [[2,6],[8,10],[15,18],[1,30]]
# nonSorted.sort(key=lambda x: x[0])
# print(nonSorted) # [[1, 3], [2, 6], [8, 10], [15, 18]]
intervals = [[1,3],[2,6],[8,10],[15,18]]
def merge(intervals):
intervals.sort(key=lambda x: x[0])
merged = []
# add the first interval to merged[]
merged.append(intervals[0])
for interval in intervals:
print(interval)
if merged[-1][1] < interval[0]: # no merge, [2,6] compared to [8,10]
print('no merge')
merged.append(interval)
else:
print('merge', merged[-1][1], interval[1])
merged[-1][1] = max(merged[-1][1], interval[1] ) # choose the max of "prev" (aka: merged[-1]) or the current interval
print()
print(merged)
merge(intervals)

View File

@ -0,0 +1,6 @@
def foo(n):
for x in range(n):
yield x**3
for x in foo(5):
print (x),

View File

@ -0,0 +1,8 @@
num=[1,2,3,4]
result=[]
for x in num:
result.append(x**2)
print(result)

View File

@ -0,0 +1,66 @@
# Given a singly linked list L: L0→L1→…→Ln-1→Ln,
# reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
# You may not modify the values in the list's nodes, only nodes itself may be changed.
# Example 1:
# Given 1->2->3->4, reorder it to 1->4->2->3.
# Example 2:
# Given 1->2->3->4->5, reorder it to 1->5->2->4->3.
from collections import deque
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
def reorderList(head):
# push all into list
q = deque()
while head:
q.append(head)
head = head.next
dummy = LinkedListNode(0)
cur = dummy
even = False
while q:
node = q.pop() if even else q.popleft()
node.next = None
cur.next = node
cur = cur.next
even ^= True
return dummy.next
# create sample linked list
head = LinkedListNode(1)
head.next = LinkedListNode(2)
head.next.next = LinkedListNode(3)
head.next.next.next = LinkedListNode(4)
head.next.next.next.next = LinkedListNode(5)
# run the code
head = reorderList(head)
while head:
print(head.val, end=" ")
head=head.next

View File

@ -0,0 +1,11 @@
a = [6, 5, 4, 2, 6]
# 1 . continuous integers randomly sorted
# 2. min, max
# 3. missing -> 3
# 4. duplicate -> 6
Q: are we given min and max?
for i

View File

@ -0,0 +1,7 @@
def helper(listt):
prod = 1
for val in listt:
prod = prod*val
return prod
print(helper([1,2,3]))

View File

@ -0,0 +1,29 @@
numInvalid=0
stack=[]
for c in text:
if c=='(':
stack.append(c)
numInvalid+=1
elif c==')':
if not stack:
numInvalid+=1
else:
stack.pop()
numInvalid-=1
return numInvalid + len(stack)
res = 0
stack = 0
for bracket in text:
if bracket == '(':
stack += 1
if bracket == ')' and stack != 0:
stack -= 1
elif bracket == ')' and stack == 0:
res += 1
return res + stack

View File

@ -0,0 +1,36 @@
arr = [8,10,2]
# arr = [2,2]
def array_of_array_products(arr):
#[8, 10, 2]
# i = 0. left = [], right [10,2]
res = []
def helper(listt):
prod = 1
for val in listt:
prod = prod*val
return prod
print(arr)
print(helper(arr))
# for i, val in enumerate(arr):
# left = None
# right = None
# if i != 0:
# left = helper(arr[:i])
# if i != len(arr)-1:
# right = helper(arr[i+1:])
# if left and right:
# res.append(left*right)
# elif left:
# res.append(left)
# elif right:
# res.append(right)
return res
print( array_of_array_products(arr) )

View File

@ -0,0 +1,3 @@
import re
print( re.search("[aeiou]", "test") )

View File

@ -0,0 +1,68 @@
a = [6, 5, 4, 2, 6]
# 1 . continuous integers randomly sorted
# 2. min, max
# 3. missing -> 3
# 4. duplicate -> 6
# similar to this hard LC question
# https://leetcode.com/problems/first-missing-positive/
def detect(l):
pass
assert detect(a) == (3, 6)
[2,4,5,6,6]=23
[2,3,4,5,6]=17
min=2
max=6
=====
6:2
2:1
5:1
4:1
=====
2,3
sum(keys)=17
min=2
max=6
max-min=4
[1,2,4]
[1,2,3]
min+...+max
expect
2+3+4+5+6
20
actual
23
2+3+4+5+6=20
2+4+5+6+6=23
missing = sum(actual) - sum(expected)
duplicate =

51
_code/interviews/test.py Normal file
View File

@ -0,0 +1,51 @@
# map and lambda
arr = [1,2,3]
sqrt = map(lambda x: x*x, arr)
print(arr)
print( list(sqrt) )
# list comprehension
# Find all of the numbers from 1-1000 that are divisible by 7
# results = [num for num in range(1000) if num % 7 == 0]
# print(results)
# res = []
# for n in range(1000):
# if n % 7 == 0:
# res.append(n)
# print(res)
# new_list = [expression(i) for i in old_list if filter(i)]
new_list = [i**2 for i in range(1,10) if i>5]
print(new_list)
arr = [1,6,7,5,9]
list2 = [ i/2 for i in arr if i > 3 ] # expression happens first, then the filter on i happens before the expression
print( list2 )
# zip
print("start fib testing")
def fib(n):
res = [ 0 for i in range(n) ]
res[1] = 1
i=3
while i<=n:
res[i-1] = res[i-2] + res[i-3]
i+=1
print(res)
fib(3)
fib(4)
fib(10)

View File

@ -0,0 +1,54 @@
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
def hasCycle(head):
if not head:
return False
set = {}
while head:
if head in set:
return True # cycle detected
else:
set[head] = None # add node to set
# next node
head = head.next
# exited loop
return False
# map = {}
# while head:
# if head.next and head.next.val not in map:
# map[head.val] = head.next.val
# else:
# if head.next == None:
# return False
# else:
# return True
# head = head.next
# return False
head = LinkedListNode(1)
head.next = LinkedListNode(2)
head.next.next = LinkedListNode(3)
# head.next.next.next = head.next
print( hasCycle(head) )

View File

@ -0,0 +1,45 @@
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
def hasCycle(head):
if not head:
return False
slow = head
fast = head.next
while True:
# if either pointer is null, reached end of list and return False
if slow is None or fast is None or fast.next is None:
return False
# cycle detected, exit and return True
if slow is fast:
return True
# advance pointers
slow=slow.next
fast=fast.next.next
return False
head = LinkedListNode(1)
head.next = LinkedListNode(2)
head.next = head
# head.next.next = LinkedListNode(3)
# # head.next.next.next = head.next
print( hasCycle(head) )

View File

@ -0,0 +1,38 @@
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
def mergeSortedLinkedList(l1, l2):
dummy = ListNode(0)
head = dummy
while l1 and l2 :
if l1.val < l2.val :
dummy.next = l1
l1 = l1.next
else :
dummy.next = l2
l2 = l2.next
dummy = dummy.next
if l1 :
dummy.next = l1
elif l2 :
dummy.next = l2
return head.next
l1 = LinkedListNode(1)
l1.next = LinkedListNode(2)
l1.next.next = LinkedListNode(4)
l2 = LinkedListNode(1)
l2.next = LinkedListNode(3)
l2.next = LinkedListNode(4)
mergeSortedLinkedList()

View File

@ -0,0 +1,53 @@
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
l1 = LinkedListNode(1)
l1.next = LinkedListNode(2)
l1.next.next = LinkedListNode(4)
l2 = LinkedListNode(1)
l2.next = LinkedListNode(3)
l2.next.next = LinkedListNode(4)
def mergeSortedLists(l1, l2):
dummy = LinkedListNode(0)
curr = dummy
while l1 and l2:
if l1.val <= l2.val:
curr.next = l1
curr = l1
l1 = l1.next
else:
curr.next = l2
curr = l2
l2 = l2.next
while l1:
curr.next = l1
curr = l1
l1 = l1.next
while l2:
curr.next = l2
curr = l2
l2 = l2.next
return dummy.next
head = mergeSortedLists(l1, l2)
curr = head
while curr:
print(curr.val)
curr=curr.next

View File

@ -0,0 +1,43 @@
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
l1 = LinkedListNode(1)
l1.next = LinkedListNode(2)
l1.next.next = LinkedListNode(4)
l2 = LinkedListNode(2)
l2.next = LinkedListNode(3)
l2.next.next = LinkedListNode(4)
def mergeSortedLists(l1, l2):
if not l1:
return l2
if not l2:
return l1
if l1.val < l2.val:
l1.next = mergeSortedLists(l1.next, l2)
return l1
else:
l2.next = mergeSortedLists(l2.next, l1)
return l2
head = mergeSortedLists(l1, l2)
curr = head
while curr:
print(curr.val)
curr=curr.next

View File

@ -0,0 +1,25 @@
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
def palindromeLinkedList(head):
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
print(slow)
print(fast)
head = LinkedListNode(1)
head.next = LinkedListNode(2)
head.next.next = LinkedListNode(2)
head.next.next.next = LinkedListNode(1)
palindromeLinkedList(head)

View File

@ -0,0 +1,50 @@
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
def reverse(head):
curr = head
prev = None
next = None
while curr:
# save next node
next = curr.next
# reverse curr's pointer
curr.next = prev
# advance curr and prev
prev = curr
curr = next
head = prev
return head
head = LinkedListNode(1)
head.next = LinkedListNode(2)
head.next.next = LinkedListNode(3)
# print list
node = head
while node:
print(node.val)
node = node.next
head = reverse(head)
# print list
node = head
while node:
print(node.val)
node = node.next

View File

@ -0,0 +1,35 @@
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
def reverse(head):
if not head:
return
head.next = reverse(head)
head = LinkedListNode(1)
head.next = LinkedListNode(2)
head.next.next = LinkedListNode(3)
# print list
node = head
while node:
print(node.val)
node = node.next
head = reverse(head)
# print list
node = head
while node:
print(node.val)
node = node.next

View File

@ -0,0 +1,65 @@
class LinkedListNode:
def __init__(self, val):
self.val = val
self.next = None
def reverseBetween(head, m, n):
prev = None
curr = head
# move prev and curr up to m
while m>1:
prev = curr
curr = curr.next
m-=1
n-=1
# connect beginning with reversed part
connection = prev
tail = curr
while n>0:
next = curr.next
curr.next = prev
prev = curr
curr = next
n-=1
if connection:
connection.next = prev
else:
head = prev
tail.next = curr
return head
head = LinkedListNode(1)
head.next = LinkedListNode(2)
head.next.next = LinkedListNode(3)
head.next.next.next = LinkedListNode(4)
head.next.next.next.next = LinkedListNode(5)
# print list
node = head
while node:
print(node.val)
node = node.next
head = reverseBetween(head, 2, 4)
# print list
print("\nresults:")
node = head
while node:
print(node.val)
node = node.next

View File

@ -0,0 +1,50 @@
'''
https://leetcode.com/problems/count-numbers-with-unique-digits/
'''
# from math import *
import math
def isUniqueInteger(n):
mymap = dict()
while(n>0):
digit=n%10
#print(digit)
if not digit in mymap:
mymap[digit] = 1
else:
return False
n=n//10
#print(mymap)
return True
def countNumbersWithUniqueDigits(n):
count = 0
for i in range(0, pow(10, n)):
if isUniqueInteger(i):
count = count + 1
return count
def main():
# countNumbersWithUniqueDigits(None, 2)
print( countNumbersWithUniqueDigits(2) )
if __name__ == "__main__":
main()

View File

@ -0,0 +1,39 @@
'''
EPI; 6.1
'''
def main():
# the input
x = -123
s = []
# deal with negative case
is_neg = False
if x < 0:
is_neg = True
x = abs(x)
# deal with the happy case
while True:
s.append( chr( ord('0') + x%10 ) ) # ord() returns unicode of digit, chr() returns char of unicode
x//=10
if x==0:
break
print (s)
print ('-' + ''.join(reversed(s)) if is_neg else reversed(s)) # reversed() returns an iterator, ''.join() concontenates iterators
# print ('-' if is_neg else '') + ''.join(reversed(s))
if __name__ == "__main__":
main()

28
_code/math/plusOne.py Normal file
View File

@ -0,0 +1,28 @@
import math
# digits = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3]
digits = [7,2,8,5,0,9,1,2,9,5,3,6,6,7,3,2,8,4,3,7,9,5,7,7,4,7,4,9,4,7,0,1,1,1,7,4,0,0,6]
def plusOne(digits):
num = 0
exp = 0
for i in reversed(range(len(digits))):
print(num, math.pow(10, exp), pow(10, exp), 10**exp)
num += math.floor( digits[i] * (10**exp))
exp+=1
plusOne = int(num+1)
res = []
while plusOne>0:
pop = plusOne%10
res = [pop] + res
plusOne = plusOne//10
return res
print(plusOne(digits))

View File

@ -0,0 +1,36 @@
import math
num = 1534236469
def reverse(num):
# handle negative case
neg = False
if num<0:
neg = True
num = abs(num)
rev = 0
while num>0:
# pop last digit
popped = num % 10
num = math.floor(num / 10)
# handle overflow
if (rev > 2**31 / 10) or (rev == 2**31 / 10 and popped>7): return 0
if (rev < -2**31 / 10) or (rev == -2**31 / 10 and popped<-8): return 0
rev = rev * 10 + popped
print(num, popped, rev)
return rev*-1 if neg else rev
print( reverse(num) )
# print( reverse(123) )
# print( reverse(-123) )
# print( reverse(2**31) )
# print( reverse(-2**31) )

View File

@ -0,0 +1,18 @@
'''
EPI; 6.1
'''
def main():
# the input
x = -123
if __name__ == "__main__":
main()

25
_code/math/uglyNum2.py Normal file
View File

@ -0,0 +1,25 @@
n=1690
def nthUglyNumber(n):
uglyNums = [1]
curr = 2
while len(uglyNums)<n:
print(curr)
# factorize
if curr%5==0 and int(curr/5) in uglyNums:
uglyNums.append(curr)
elif curr%3==0 and int(curr/3) in uglyNums:
uglyNums.append(curr)
elif curr%2==0 and int(curr/2) in uglyNums:
uglyNums.append(curr)
curr+=1
return uglyNums[-1]
print(nthUglyNumber(n))

View File

@ -0,0 +1,45 @@
bo = [
[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]
]
print( bo[1][2] ) # 1 down, 2 right
print(len(bo))
print()
print('\nprinting row')
for i in range(len(bo)-1):
print(bo[0][i])
print('\nprinting col')
for col in range(len(bo)-1):
print(bo[col][0])
print('\nprint both (horizontally first)')
for row in range(len(bo)):
print(bo[row])
print('\nprint both (horizontally first, element by element)')
for row in range(len(bo)): # horizontal first, loop over "row" first
print(bo[row])
for col in range(len(bo[0])):
print(bo[row][col])
print('\nprint both (vertically first, element by element)')
for col in range(len(bo[0])): # vertical first, loop over col first
print("row of :" + str(bo[0][col] ) )
for row in range(len(bo)):
print(bo[row][col])
print('\njust gets first column using list comprehension')
print( [i[0] for i in bo] )

View File

@ -0,0 +1,43 @@
'''
rotate 90 degree = transpose + flip horizontally
https://www.geeksforgeeks.org/rotate-matrix-90-degree-without-using-extra-space-set-2/?ref=rp
'''
mat = [
[1,2,3],
[4,5,6],
[7,8,9]
]
def rotateMatrix(mat):
n = len(mat)
for i in range(n):
for j in range(i,n):
tmp = mat[i][j]
mat[i][j] = mat[j][i]
mat[j][i] = tmp
for row in mat:
print(row)
print("after second rotation")
for i in range(n):
for j in range(n//2):
tmp = mat[i][j]
mat[i][j] = mat[i][n-j-1]
mat[i][n-j-1] = tmp
for row in mat:
print(row)
return mat
print(rotateMatrix(mat))
# for row in mat:
# print(row)

Some files were not shown because too many files have changed in this diff Show More