Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Problem1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#Problem1: https://leetcode.com/problems/peeking-iterator/description/
# Time Complexity: O(n),We loop through the prices list once, comparing each day to the previous day, so the work grows linearly with the number of days

# Space Complexity: O(1),We only use a single variable to store profit, no extra data structures like memo tables or arrays are used
# Approach:
# Since we can buy and sell unlimited times with no cost, we do not need to track actual buy and sell days
# Instead we walk through the prices day by day and any time todays price is higher than yesterdays, we treat that rise as its own small profit and add it to our total
# Any day where the price drops or stays the same, we simply skip it since there is nothing to gain

class Solution:
def maxProfit(self, prices: List[int]) -> int:
profit = 0 # this will store our running total profit, starts at 0 since we have not looked at any days yet

for i in range(1,len(prices)): # start from index 1 since we always compare todays price to the previous day, day 0 has no previous day
if prices[i]>prices[i-1]: # check if todays price is higher than yesterdays price, meaning there was a profitable rise
profit += prices[i]-prices[i-1] # add that days gain to our running profit total, this is the greedy move, grab the gain right away
return profit # after checking every consecutive pair of days, return the total profit we collected
79 changes: 79 additions & 0 deletions Problem2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#Problem2: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/
# Time Complexity: O(1) for peek(), next() and hasNext(), since each just reads or updates a stored value
# Space Complexity: O(1), we only store one extra value ahead of time, not the whole list
# Approach:
# We keep one element pre fetched in self.nextnumber at all times
# peek() just returns this stored value without touching the iterator
# next() returns the stored value, then pulls the next one from the iterator to refill it
# hasNext() checks if there is a stored value left, since it becomes None when the iterator runs out

# Below is the interface for Iterator, which is already defined for you.
#
# class Iterator:
# def __init__(self, nums):
# """
# Initializes an iterator object to the beginning of a list.
# :type nums: List[int]
# """
#
# def hasNext(self):
# """
# Returns true if the iteration has more elements.
# :rtype: bool
# """
#
# def next(self):
# """
# Returns the next element in the iteration.
# :rtype: int
# """

class PeekingIterator:
def __init__(self, iterator):
"""
Initialize your data structure here.
:type iterator: Iterator
"""
self.iterator = iterator
# keep a reference to the raw iterator so we can pull more values later
self.nextnumber = self.iterator.next()
# pre fetch the first value right away, this is our one ahead buffer

def peek(self):
"""
Returns the next element in the iteration without advancing the iterator.
:rtype: int
"""
return self.nextnumber
# just return the stored value, nothing moves since we are only reading

def next(self):
"""
:rtype: int
"""
temp = self.nextnumber
# save the current stored value, this is what we will return

self.nextnumber = None
# clear it for now, we are about to check if there is more to pull

if self.iterator.hasNext():
# check the raw iterator, not our own hasNext, since our own nextnumber was just cleared
self.nextnumber = self.iterator.next()
# refill the buffer with the next value from the raw iterator

return temp
# return the value that was cached before this call started

def hasNext(self):
"""
:rtype: bool
"""
return self.nextnumber is not None
# if nextnumber is still holding a value, there is more left to give

# Your PeekingIterator object will be instantiated and called as such:
# iter = PeekingIterator(Iterator(nums))
# while iter.hasNext():
# val = iter.peek() # Get the next element but not advance the iterator.
# iter.next() # Should return the same value as [val].