Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
navidre authored May 8, 2024
1 parent 1f8e75e commit 8d4127a
Showing 1 changed file with 39 additions and 25 deletions.
64 changes: 39 additions & 25 deletions tutorial/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,42 +45,56 @@ In programming, managing collections of data efficiently is crucial for performa
- **No False Negatives**: If a Bloom filter reports an element as absent, it is definitively not present.
- **No Element Removal**: Bloom filters do not support direct element removal as it would affect the integrity of other elements due to shared hash functions.

# Pattern Code Templates
# Template ctarter codes for patterns

## Dynamic Programming
## Dynamic Programming


### 1. Top-Down Memoization (Recursive)

This approach uses recursion to break down the problem into smaller subproblems, caching results to avoid redundant calculations.

```python
def solve_problem(input1, input2, ...):
# Dictionary to store the intermediate results
memo = {}

# Helper function that performs the recursive computation
def dp(state1, state2, ...):
# Convert current state to a tuple or a form that can be used as a dictionary key
memo_key = (state1, state2, ...)

# Check if the result for the current state is already computed
if memo_key in memo:
return memo[memo_key]
def solve_top_down(input1, input2):
memo = {} # Cache for storing results of subproblems

# Base case: define stopping condition for recursion
if base_case_condition:
def dp(state1, state2):
if (state1, state2) in memo: # Check if result is already computed
return memo[(state1, state2)]

if state1 == 0 or state2 == 0: # Base case example
return base_case_result

# Recursive case: calculate the result and store in memo
result = compute_result(dp, state1 - 1, state2 - 1)
memo[(state1, state2)] = result
return result

# Compute the result recursively and store it in the memo
result = 0 # Initialize result according to the problem requirement
# Compute result considering various transitions and choices
result = compute_result_based_on_transitions(dp, state1, state2, ...)
return dp(input1, input2)
```

# Save the result in memo before returning
memo[memo_key] = result
return result
### 2. Bottom-Up Tabulation (Iterative)

This approach fills a table iteratively based on the smallest subproblems, building up to the solution of the original problem.

```python
def solve_bottom_up(input1):
dp = [0] * (input1 + 1) # DP array to store the results of subproblems
dp[0] = base_case_result # Initialize base case

# Initial call to the dp function with the initial state
return dp(initial_state1, initial_state2, ...)
for i in range(1, input1 + 1):
dp[i] = dp[i - 1] + some_value # Fill dp array iteratively

return dp[input1] # Return the result for the original problem
```

### Explanation of Comments

- **Comments in the Code**: These comments explain each part of the code, from initialization of data structures (like the memoization dictionary or DP array) to the handling of base cases and the iterative or recursive calculation of results.
- **Purpose**: The comments are designed to make the code self-explanatory, illustrating the logic and flow of data, which is essential for understanding and debugging dynamic programming solutions.

These templates and comments should help you build a solid understanding of dynamic programming and how to implement it in various scenarios.

# Sliding Window

The sliding window technique is a method used to solve problems that involve arrays or lists, especially when you're asked to find a subarray that satisfies certain conditions. This technique is particularly useful for problems where you need to consider contiguous elements together. The key idea is to maintain a 'window' that slides over the data to examine different subsets of it.
Expand Down

0 comments on commit 8d4127a

Please sign in to comment.