Objected Oriented Programming
Object-Oriented Programming (OOP) is a programming paradigm centered around objects — which bundle data (attributes) and behavior (methods) together.
Instead of writing code as a series of steps (procedural programming), OOP organizes code into classes that create objects — like blueprints and the actual items built from them.
ConceptDescriptionExample (Python)
| Class | A blueprint for creating objects | class Car: |
| Object | An instance of a class | my_car = Car() |
| Encapsulation | Hiding internal data using methods and attributes | Private attributes with getters/setters |
| Abstraction | Showing only essential details, hiding complexity | A Car.start() method hides engine logic |
| Inheritance | One class can derive from another, reusing code | class ElectricCar(Car): |
| Polymorphism | Methods behave differently based on the object | Both Car and Boat implement move() differently |
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.
class Node:
def __init__(self, key = None, val = None, prev = None, next = None):
self.val = val
self.prev = prev
self.next = next
self.key = key
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.map = {}
self.head = Node()
self.tail = Node()
self.head.next = self.tail
self.tail.prev = self.head
def get(self, key: int) -> int:
if key in self.map:
self.delNode(key)
self.addLast(key)
return self.map[key].val
else:
return -1
def put(self, key: int, value: int) -> None:
if key not in self.map:
if len(self.map) < self.capacity:
self.map[key] = Node(key = key, val = value)
self.addLast(key)
else:
self.map[key] = Node(key = key, val = value)
delKey = self.head.next.key
self.delNode(delKey)
self.addLast(key)
del self.map[delKey]
else:
self.map[key].val = value
self.delNode(key)
self.addLast(key)
def addLast(self, key):
prev = self.tail.prev
cur = self.map[key]
prev.next = cur
cur.prev = prev
self.tail.prev = cur
cur.next = self.tail
def delNode(self, key):
cur = self.map[key]
prev = cur.prev
next = cur.next
prev.next = next
next.prev = prev
Min Stack
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
Implement the MinStack class:
- MinStack() initializes the stack object
- void push(int val) pushes the element val onto the stack.
- void pop() removes the element on the top of the stack.int top() gets the top element of the stack.
- int getMin() retrieves the minimum element in the stack.
You must implement a solution with O(1) time complexity for each function.
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.arr = []
self.heap = []
self.remove = set()
self.id = 0
def push(self, val: int) -> None:
self.arr.append((val, self.id))
heapq.heappush(self.heap, (val, self.id))
self.id += 1
def pop(self) -> None:
last = self.arr.pop()
self.remove.add(last[1])
self.clean()
return last[0]
def top(self) -> int:
last = self.arr[-1]
return last[0]
def getMin(self) -> int:
return self.heap[0][0]
def clean(self):
while self.heap and self.heap[0][1] in self.remove:
v, index = heapq.heappop(self.heap)
self.remove.remove(index)
[GoValley-Jo] OOP 13
By ZhiTongGuiGu
[GoValley-Jo] OOP 13
- 5