Skip to content

Commit

Permalink
add leetcode challenges
Browse files Browse the repository at this point in the history
  • Loading branch information
jbcodeforce committed Jun 2, 2024
1 parent e7395ab commit f578817
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 0 deletions.
18 changes: 18 additions & 0 deletions algorithms/binarySearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,21 @@ def binarySearch(sortedArray,target):

a=[1,2,3,4,5,6,7,8,9,10,11,12]
print(binarySearch(a,9))


def search(sortedArray, v) -> bool:
m = len(sortedArray)
if m == 0:
return False
idx = m//2
print(f"a={sortedArray[idx]} and {sortedArray} and i:{idx}")
if sortedArray[idx] == v:
return True
elif sortedArray[idx] < v:
# search in [idx+1, m]
return search(sortedArray[idx+1:m],v)
else:
# search in [0, idx-1]
return search(sortedArray[0:idx],v)

print(search(a,9))
28 changes: 28 additions & 0 deletions algorithms/duplicates_in.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
Contains Duplicate
Given an integer array nums, return true if any value appears at least
twice in the array, and return false if every element is distinct.
Input: nums = [1,2,3,1]
Output: true
Input: nums = [1,2,3,4]
Output: false
Input: nums = [1,1,1,3,3,4,3,2,4,2]
Output: true
"""

def duplicate_in(nums)-> bool:
encounters = []
for i in nums:
if i not in encounters:
encounters.append(i)
else:
return True
return False

assert duplicate_in([1,2,3,1])

assert not duplicate_in([1,2,3,4])

assert duplicate_in([1,1,1,3,3,4,3,2,4,2])
71 changes: 71 additions & 0 deletions algorithms/max_subarray.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""
Given an integer array nums, find the
subarray with the largest sum, and return its sum.
what is a subarray? it can be the array itself, or contiguous number from 1 to n elements
n <= len(array)
Given nums = [-2,1,-3,4,-1,2,1,-5,4]
sub_array=[-2] sum=-2
sub_array=[-2,1] sum=-1
sub_array=[-2,1,-3]
sub_array=[4,-1,2,1] sum=6 will be the biggest
"""


def sum_array(nums: []) -> int:
"""
return the sum of the int within the given array
"""
sum = 0
for i in nums:
sum+=i
return sum

def build_sub_array(nums: [],i,j)-> []:
return nums[i:j]

def max_subarray(nums: []) -> int:
"""
brut force method, build the contiguous sub array, compute the sum of sub array and
compare to the current max
"""
max = -10000
subarray=[]
for i in range(0,len(nums)):
for j in range(i+1,len(nums)+1):
s_a=build_sub_array(nums,i,j)
sum_s_a=sum_array(s_a)
if sum_s_a> max:
max = sum_s_a
subarray=s_a
return (subarray,max)

def better_sol(nums: []) -> int:
"""
For O(n) we need one loop and when current sum is < 0 then we change sub array
"""
max = -10000
current_sum =0
subarray=[]
new_idx=0
for i in range(0,len(nums)):
current_sum +=nums[i]
if current_sum < 0:
current_sum = 0
subarray=[]
new_idx=i+1
else:
if current_sum > max:
max=current_sum
subarray=nums[new_idx:i+1]

return (subarray,max)

nums=[-2,1,-3,4,-1,2,1,-5,4]

print(max_subarray(nums))
assert ([4, -1, 2, 1], 6) == max_subarray(nums)
print(max_subarray([1]))
print(max_subarray([5,4,-1, 7, 8]))
print(better_sol(nums))
77 changes: 77 additions & 0 deletions algorithms/palindrome.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""
Given an integer x, return true if x is a
palindrome, and false otherwise.
palindrome a number or string that can be read from both direction.
Could you solve it without converting the integer to a string?
"""
import math
def length(n: int) -> int:
l=1
if (n < 0):
n=-n
while n >= 10:
n=n//10
l+=1
return l

def is_palindrome(n: int) -> bool:
if n < 0:
return False
l = []
nb_digits : int = length(n)
z=n
e=nb_digits-1
while len(l) < nb_digits:
div = math.pow(10,e)
r = z % div
a = z // div
l.append(a)
z=r
e-=1
print(div, a, r)
print(l)
i=0
j=nb_digits-1
while i<=j:
if l[i] != l[j]:
return False
i+=1
j-=1
return True

def better_sol(n: int) -> bool:
"""
reverse the number and reversed and n should be the same.
To reverse the number add the rest of div / 10 to current reversed number * 10
t=121 reversed = 1
t=12 reversed = 12
t=1 reversed = 121
"""
if n < 0:
return False
reversed = 0
temp = n
while temp != 0:
r = temp % 10
reversed = reversed * 10 + r
temp //=10
return reversed == n

assert length(1) == 1
assert length(12) == 2
assert length(212) == 3
assert length(-212) == 3
assert length(3142) == 4

assert is_palindrome(1)
assert is_palindrome(11)
assert is_palindrome(121)
assert not is_palindrome(-121)
assert not is_palindrome(1341)
assert is_palindrome(1234321)
assert better_sol(1234321)



65 changes: 65 additions & 0 deletions algorithms/remove_el.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""
Remove element
Given an integer array nums and an integer val, remove all occurrences of val
in nums in-place.
The order of the elements may be changed. Then return the number of elements
in nums which are not equal to val
nums
"""
from typing import List

def remove_element_1(nums: List[int],val: int) -> (int,List[int]):
c=0
for i in range(0,len(nums)):
if nums[i] == val:
nums[i]=None
c+=1
for k in range(0,len(nums)):
if nums[k] == None:
for j in range(k,len(nums)):
if nums[j] != None:
nums[k] = nums[j]
nums[j] = None
break
return (len(nums)-c,nums)

def remove_element(nums: List[int],val: int) -> (int,List[int]):
c=0
for i in range(0,len(nums)):
if nums[i] == val:
nums[i]= None
for k in range(len(nums)-1,i,-1):
if nums[k] != val and nums[k] != None:
nums[i]=nums[k]
nums[k]=None
break
c+=1
return (len(nums)-c,nums)

def better_sol(nums: List[int],val: int) -> (int,List[int]):
"""
use index of the non target element
"""
idx = 0
for i in range(len(nums)):
if nums[i] != val:
nums[idx]= nums[i]
idx+=1
return (idx,nums)

nums=[3,2,2,3]
val=3
expected_num=[2,2,None,None]

k,en = remove_element(nums,val)
print(k,en)
assert k == 2
assert expected_num == en
nums = [0,1,2,2,3,0,4,2]
val = 2
k,en = better_sol(nums,val)
print(k,en)
assert k == 5
assert en[0:k] == [0,1,3,0,4]
54 changes: 54 additions & 0 deletions algorithms/roman_to_int.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
matching values 1,5,10,50,100,500,1000
Roman numerals are usually written largest to smallest from left to right.
Some rules to respect:
I can be placed before V (5) and X (10) to make 4 and 9.
X can be placed before L (50) and C (100) to make 40 and 90.
C can be placed before D (500) and M (1000) to make 400 and 900.
Approach: parse roman number representation char by char and match the char read
to a k in a dict to get matching value.
"""

symbols = { 'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}


def roman_to_int(roman: str) -> int:
n=0
i = 0
previous = ''
while i < len(roman):
c = roman[i]
if (c == 'V' or c == 'X') and previous == 'I':
n=n+symbols[c]-2
elif (c == 'L' or c == 'C') and previous == 'X':
n=n+symbols[c]-20
elif (c == 'D' or c == 'M') and previous == 'C':
n=n+symbols[c]-200
else:
n=n+symbols[c]
previous=c
i+=1
return n


def better_sol(roman: str) -> int:
ans = 0

for i in range(len(roman)):
if i < len(roman) - 1 and symbols[roman[i]] < symbols[roman[i+1]]:
ans -= symbols[roman[i]]
else:
ans += symbols[roman[i]]

return ans

assert roman_to_int("III") == 3
assert roman_to_int("IV") == 4
assert roman_to_int("IX") == 9
assert roman_to_int("XL") == 40
assert roman_to_int("XC") == 90
assert roman_to_int("LVII") == 57
assert better_sol("MCMXCIV") == 1994
54 changes: 54 additions & 0 deletions algorithms/two_sum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
Given an array of integers nums and an integer target, return indices
of the two numbers such that they add up to target.
numbers are > 0, nums is not sorted, we can have the same number multiple times in nums
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Input: nums = [3,2,4], target = 6
Output: [1,2]
O(log N)
"""
from typing import List

def two_sum_O2(nums, target) -> (int, int):
"""
brute force is to loop over the array and look at the numbers above to find
the complement and return the first match
"""
for i in range(0,len(nums)-1):
for j in range(i+1,len(nums)):
if nums[i] + nums[j] == target:
return (i,j)
return (-1,-1)


def two_sum(nums: List[int], target: int) -> (int, int):
"""
loop over the list in one shot.
use a list of complement from current number to the target if there is no
one existing in the complements already
O(log(n))
"""
complements=[]
for i in range(0,len(nums)):
# do we have a complement
comp = target-nums[i]
for j in range(0,len(complements)):
p_i, c = complements[j]
if nums[i] == c:
return (p_i,i)
if nums[i] < target:
complements.append((i,comp))
return (-1,-1)

a,b= two_sum([2,7,11,15],9)

print(a,b)

print(two_sum([3,2,4],6))
print(two_sum([3,2,4],8))
print(two_sum([3,3],6))

0 comments on commit f578817

Please sign in to comment.