diff --git a/Problem1.py b/Problem1.py new file mode 100644 index 0000000..ed4e6cb --- /dev/null +++ b/Problem1.py @@ -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 \ No newline at end of file diff --git a/Problem2.py b/Problem2.py new file mode 100644 index 0000000..a1a7d54 --- /dev/null +++ b/Problem2.py @@ -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]. \ No newline at end of file