# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: # Time: O(n) Space: O(1) defreverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: prev, curr = None, head while curr: next = curr.next# save next node before we break the pointer curr.next = prev # point to previous node prev = curr # shift previous pointer curr = next# shift current pointer
# e.g. # 1 -> 2 -> 3 -> 4 # ^ ^ # head head.next # # 4 -> 3 -> 2 -> 1 -> None # ^ ^ ^ # newHead head.next head newHead = head if head.next: newHead = self.reverseList(head.next) head.next.next = head head.next = None
return newHead
[Leetcode 25] Reverse Nodes in k-Group
Given the head of a linked list, reverse the nodes of the list k at a time, and return the modified list.
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should remain as it is.
You may not alter the values in the list’s nodes, only nodes themselves may be changed.
Example 1:
1 2
Input: head = [1,2,3,4,5], k = 2 Output: [2,1,4,3,5]
Example 2:
1 2
Input: head = [1,2,3,4,5], k = 3 Output: [3,2,1,4,5]
Constraints:
The number of nodes in the list is n.
1 <= k <= n <= 5000
0 <= Node.val <= 1000
Follow-up: Can you solve the problem in O(1) extra memory space?
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defreverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]: # check if reverse is needed curr = head for _ inrange(k): ifnot curr: return head # no need to reverse, thus return the original head curr = curr.next
# Reverse the sub-list with k nodes # e.g. # None 1 -> 2 -> 3 -> 4 -> 5 -> 6, k = 3 # ^ ^ # prev head(curr) # # After reverse the first 3 nodes, # 3 -> 2 -> 1 -> 4 -> 5 -> 6 # ^ ^ ^ # prev head curr prev, curr = None, head for _ inrange(k): next = curr.next# save the next before we break the pointer curr.next = prev # point to previous node(reverse) prev = curr # shift previous pointer curr = next# shift current pointer
# after reverse, the curr pointer points to the "head" of next k nodes, # and the previous pointer points to the new "head" of the reversed k nodes. head.next = self.reverseKGroup(curr, k)
# the previous pointer points to the head of reversed list return prev
[Leetcoe 146] LRU Cache
Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.
Implement the LRUCache class:
LRUCache(int capacity) Initialize the LRU cache with positive size capacity.
int get(int key) Return the value of the key if the key exists, otherwise return -1.
void put(int key, int value) Update the value of the key if the key exists. Otherwise, add the key-value pair to the cache. If the number of keys exceeds the capacity from this operation, evict the least recently used key.
The functions get and put must each run in O(1) average time complexity.
# dummy head and tail for the doubled-linked list self.head = self.Node() self.tail = self.Node() self.head.next = self.tail self.tail.prev = self.head
defdeleteNode(self, node): prev = node.prev next = node.next prev.next = next next.prev = prev
defget(self, key: int) -> int: if key in self.cache: node = self.cache[key] val = node.val del self.cache[key] self.deleteNode(node) self.addNode(node) self.cache[key] = self.head.next return val else: return -1
defput(self, key: int, value: int) -> None: if key in self.cache: node = self.cache[key] del self.cache[key] self.deleteNode(node)
# delete the least recently used node when the capacity is full iflen(self.cache) == self.cap: del self.cache[self.tail.prev.key] self.deleteNode(self.tail.prev)
# insert the most recent used node to the front self.addNode(self.Node(key, value)) self.cache[key] = self.head.next
# Your LRUCache object will be instantiated and called as such: # obj = LRUCache(capacity) # param_1 = obj.get(key) # obj.put(key,value)
[Leetcode 224] Basic Calculator
Given a string s representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation.
Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval().
Example 1:
1 2
Input: s = "1 + 1" Output: 2
Example 2:
1 2
Input: s = " 2 - (3 + 4) " Output: -5
Example 3:
1 2
Input: s = "(1+(4+5+2)-3)+(6+8)" Output: 23
Constraints:
1 <= s.length <= 3 * 10^5
s consists of digits, ‘+’, ‘-‘, ‘(‘, ‘)’, and ‘ ‘.
s represents a valid expression.
‘+’ is not used as a unary operation (i.e., “+1” and “+(2 + 3)” is invalid).
‘-‘ could be used as a unary operation (i.e., “-1” and “-(2 + 3)” is valid).
There will be no two consecutive operators in the input.
Every number and running calculation will fit in a signed 32-bit integer.
classSolution: defcalculate(self, s: str) -> int: """ Refer to https://leetcode.com/problems/basic-calculator/solutions/546092/simple-python-solution-using-stack-with-explanation-inline/?envType=study-plan-v2&envId=top-interview-150 1. Take 3 containers: num -> to store current num value only sign -> to store sign value, initially +1 res -> to store sum When ( comes these containers used for calculate sum of intergers within () brackets. -------------------- 2. When c is + or - Move num to res, because we need to empty num for next integer value. set num = 0 sign = update with c -------------------- 3. When c is '(' Here, we need num, res, sign to calculate sum of integers within () So, move num and sign to stack => [num, sign] Now reset - res = 0, num = 0, sign = 1 (default) -------------------- 4. When c is ')' -> 2-(3+4), Here res=3, num=4, sign=1 stack [2, -] res +=sign*num -> calculate sum for num first, then pop items from stack, res=7 res *=stack.pop() - > Pop sign(+ or -) to multiply with res, res = 7*(-1) res +=stack.pop() - > Pop integer and add with prev. sum, res = -7 + 2 - 5 -------------------- Simple Example: 2 - 3 Initially res will have 2,i.e. res = 2 then store '-' in sign. it will be used when 3 comes. ie. sign = -1 Now 3 comes => res = res + num*sign Return statement: res+num*sign => res = 2 + 3(-1) = 2 - 3 = -1 """ num = 0 sign = 1 res = 0 stack = [] for i inrange(len(s)): # iterate characters c = s[i] if c.isdigit(): # parse the consecutive digits. e.g. 23 -> 2 * 10 + 3 num = num*10 + int(c) elif c in'-+': # check for - and + # calculate the temporary result before '+' or '-' res += num*sign # save the new sign sign = -1if c == '-'else1 # reset num to 0 for parsing the next operand num = 0 elif c == '(': # we need res and sign to save the temporary result within '()'. Reset sign to default 1. stack.append(res) stack.append(sign) res = 0 sign = 1 elif c == ')': # calculate the result within '()' # e.g. 2 -(3 + 4) -> res = 3, num = 4, sign = 1, stack = [2, -] res +=sign*num # res = 3 * 1 + 4 = 7 res *=stack.pop() # res = 7 * (-1) = -7 res +=stack.pop() # res = -7 + 2 = -5 num = 0# reset num to 0 return res + num*sign
while i < len(s): if s[i].isdigit(): # parse the operand digits = digits * 10 + int(s[i]) elif s[i] in'+-': # evaluate the subresult before the next operator res += digits * sign