Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shortest path algorithms and practice problems for various algorithms in graphs #37

Merged
merged 3 commits into from
Oct 4, 2024
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
### Linear DP
- [Climbing Stairs](https://leetcode.com/problems/climbing-stairs/)
- [House robber](https://leetcode.com/problems/house-robber/)
- [Word Break](https://leetcode.com/problems/word-break/)
- [Coin Change](https://leetcode.com/problems/coin-change/)
- [Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/)

### String DP
- [Palindromic Partitioning](https://leetcode.com/problems/palindrome-partitioning/)
- [Palindromic Partitioning II](https://leetcode.com/problems/palindrome-partitioning-ii/)
- [Word break](https://leetcode.com/problems/word-break/)

### Knapsack based DP
- [Target Sum](https://leetcode.com/problems/target-sum/)
- [House Robber II](https://leetcode.com/problems/house-robber-ii/)
- [0/1 Knapsack Problem](https://leetcode.com/problems/0-1-knapsack-problem/)
- [Coin Change II](https://leetcode.com/problems/coin-change-ii/)
- [Minimum Subset Sum Difference](https://leetcode.com/problems/minimum-subset-sum-difference/)

### Grid based DP
- [Unique Paths](https://leetcode.com/problems/unique-paths/)
- [Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/)
- [Coin Path](https://leetcode.com/problems/coin-path/)
- [Number of Islands](https://leetcode.com/problems/number-of-islands/)
- [Word Search](https://leetcode.com/problems/word-search/)
- [Longest Increasing Path in a Matrix](https://leetcode.com/problems/longest-increasing-path-in-a-matrix/)

### DP on intervals(Partition DP)
- [Burst Balloons](https://leetcode.com/problems/burst-balloons/)
- [Palindrome Partitioning II](https://leetcode.com/problems/palindrome-partitioning-ii/)
- [Largest Divisible Subset](https://leetcode.com/problems/largest-divisible-subset/)
- [Non-overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/)
- [Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/)
8 changes: 8 additions & 0 deletions docs/Dynamic Programming/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Dynamic Programming",
"position": 16,
"link": {
"type": "generated-index",
"description": "Dynamic Programming is a powerful technique used in algorithm design to solve complex problems by breaking them down into simpler subproblems. It is particularly effective for optimization problems where the solution can be constructed from solutions to subproblems. Dynamic Programming is commonly used in various fields, including computer science, operations research, and economics, and is characterized by overlapping subproblems and optimal substructure."
}
}
29 changes: 29 additions & 0 deletions docs/Dynamic Programming/approaches.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
id: dynamic-programming-approaches
title: Approaches in Dynamic Programming
sidebar_label: Approaches in Dynamic Programming
description: "In this blog post, we'll explore the approaches used in Dynamic Programming (DP), a powerful technique for solving complex problems by breaking them down into simpler subproblems. You'll learn about the two main approaches—Top-Down and Bottom-Up—how they work, their pros and cons, and examples to illustrate their application."
tags: [dsa, algorithms, dynamic-programming]
---

## Approaches in Dynamic Programming
There are two main approaches to solving DP problems:

- ## Top-Down Approach (Memoization):

In this approach, you start with the main problem and recursively break it down into subproblems. When you solve a subproblem, you store its result in a data structure (usually an array or hash table) so that the next time you need to solve the same subproblem, you can retrieve the stored result instead of recalculating it.

- **Pros**: Easier to implement, especially for problems where the recursive structure is clear.
- **Cons**: Can have higher space complexity due to the recursion stack, and there might be overhead from recursive calls.

**Example**: Fibonacci sequence calculation using memoization.


- ## Bottom-Up Approach (Tabulation):

In this approach, you solve all possible subproblems first, typically in a tabular format. You start with the smallest subproblems and work your way up to the main problem, filling in a table (usually an array) with the solutions to subproblems.

- **Pros**: Generally more space-efficient and avoids the overhead of recursive calls.
- **Cons**: Can be less intuitive to implement for some problems compared to the top-down approach.

**Example**: Solving the 0/1 Knapsack problem using tabulation.
17 changes: 17 additions & 0 deletions docs/Dynamic Programming/how_to_identify.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
id: identifying-dynamic-programming-problem
title: Identifying a Dynamic Programming Problem
sidebar_label: Identifying a Dynamic Programming Problem
description: "In this blog post, we'll explore how to identify problems that can be effectively solved using Dynamic Programming (DP) techniques, focusing on the key properties of optimal substructure and overlapping subproblems."
tags: [dsa, algorithms, dynamic programming]
---

To identify whether a problem can be solved using Dynamic Programming (DP), you typically look for two key properties:

### Optimal Substructure:

- A problem exhibits optimal substructure if an optimal solution to the problem can be constructed from optimal solutions to its subproblems. In other words, if you can solve a problem by combining the solutions of smaller instances of the same problem, it likely has optimal substructure.

### Overlapping Subproblems:

- A problem has overlapping subproblems if the same subproblems are solved multiple times during the computation of the solution. DP is useful when the same calculations are needed multiple times, and it allows you to store and reuse these solutions to avoid redundant work.
56 changes: 56 additions & 0 deletions docs/graphs/Practice Problems.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
### BFS Problems
- [Flood Fill](https://leetcode.com/problems/flood-fill/)
- [Number of Islands](https://leetcode.com/problems/number-of-islands/)
- [Word Ladder I](https://leetcode.com/problems/word-ladder/)
- [Word Ladder II](https://leetcode.com/problems/word-ladder-ii/)
- [Evaluate Division](https://leetcode.com/problems/evaluate-division/)
- [Get Watched Videos by Your Friends](https://leetcode.com/problems/get-watched-videos-by-your-friends/)
- [Cut Off Trees for Golf Event](https://leetcode.com/problems/cut-off-trees-for-golf-event/)

### DFS Problems
- [Number of Islands](https://leetcode.com/problems/number-of-islands/)
- [Flood Fill](https://leetcode.com/problems/flood-fill/)
- [Longest Increasing Path in a Matrix](https://leetcode.com/problems/longest-increasing-path-in-a-matrix/)
- [Evaluate Division](https://leetcode.com/problems/evaluate-division/)
- [Robot Room Cleaner](https://leetcode.com/problems/robot-room-cleaner/)
- [Most Stones Removed with Same Row or Column](https://leetcode.com/problems/most-stones-removed-with-same-row-or-column/)
- [Reconstruct Itinerary](https://leetcode.com/problems/reconstruct-itinerary/)
- [Tree Diameter](https://leetcode.com/problems/tree-diameter/)
- [Accounts Merge](https://leetcode.com/problems/accounts-merge/)

### Connected Components Problems
- [Number of Provinces](https://leetcode.com/problems/number-of-provinces/)
- [Number of Connected Components in an Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/)
- [Number of Operations to Make Network Connected](https://leetcode.com/problems/number-of-operations-to-make-network-connected/)
- [Accounts Merge](https://leetcode.com/problems/accounts-merge/)
- [Critical Connections in a Network](https://leetcode.com/problems/critical-connections-in-a-network/)

### Dijkstra's Problems
- [Path With Maximum Minimum Value](https://leetcode.com/problems/path-with-maximum-minimum-value/)
- [Network Delay Time](https://leetcode.com/problems/network-delay-time/)
- [Path with Maximum Probability](https://leetcode.com/problems/path-with-maximum-probability/)
- [Path With Minimum Effort](https://leetcode.com/problems/path-with-minimum-effort/)
- [Cheapest Flights Within K Stops](https://leetcode.com/problems/cheapest-flights-within-k-stops/)

### Union Find Problems
- [Number of Islands](https://leetcode.com/problems/number-of-islands/)
- [Largest Component Size by Common Factor](https://leetcode.com/problems/largest-component-size-by-common-factor/)
- [Most Stones Removed with Same Row or Column](https://leetcode.com/problems/most-stones-removed-with-same-row-or-column/)
- [Number of Connected Components in an Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/)

### Minimum Spanning Tree Problems
- [Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/)
- [Min Cost to Connect All Points](https://leetcode.com/problems/min-cost-to-connect-all-points/)

### Topological Sort Problems
- [Course Schedule](https://leetcode.com/problems/course-schedule/)
- [Course Schedule II](https://leetcode.com/problems/course-schedule-ii/)
- [Sequence Reconstruction](https://leetcode.com/problems/sequence-reconstruction/)
- [Alien Dictionary](https://leetcode.com/problems/alien-dictionary/solution/)

### Floyd-Warshall Problems
- [Find the City With the Smallest Number of Neighbors at a Threshold Distance](https://leetcode.com/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/)
- [Network Delay Time](https://leetcode.com/problems/network-delay-time/)

### Bellman-Ford Problems
- [Network Delay Time](https://leetcode.com/problems/network-delay-time/)
167 changes: 167 additions & 0 deletions docs/graphs/Shortest Path Algorithms/BellManFord Algorithm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
---
id: bellman-ford
title: Bellman-Ford Algorithm
sidebar_label: Bellman-Ford Algorithm
description: "In this blog post, we'll dive into the Bellman-Ford Algorithm, a fundamental graph algorithm used to find the shortest path between nodes in a graph, even with negative weights."
tags: [dsa, algorithms, shortest path]
---

## Introduction
The **Bellman-Ford Algorithm** is an algorithm used to find the shortest path from a single source vertex to all other vertices in a weighted graph. Unlike Dijkstra’s Algorithm, Bellman-Ford works with graphs that have negative weights. However, it does not work with graphs containing negative weight cycles.

The Bellman-Ford algorithm is useful in scenarios where we expect the graph to have negative edge weights and need to detect negative weight cycles.

## Implementation

Let’s see how the Bellman-Ford Algorithm can be implemented in Java:

# Code in Java

```java
// A Java program to find the shortest path using Bellman-Ford algorithm
public class BellmanFord {
// A class to represent a weighted edge in a graph
class Edge {
int src, dest, weight;
Edge() {
src = dest = weight = 0;
}
}

int V, E;
Edge edge[];

// Constructor
BellmanFord(int v, int e) {
V = v;
E = e;
edge = new Edge[e];
for (int i = 0; i < e; ++i)
edge[i] = new Edge();
}

// Function to find the shortest path
void bellmanFord(BellmanFord graph, int src) {
int V = graph.V, E = graph.E;
int dist[] = new int[V];

// Initialize distances from src to all other vertices as INFINITE
for (int i = 0; i < V; ++i)
dist[i] = Integer.MAX_VALUE;
dist[src] = 0;

// Relax all edges |V| - 1 times
for (int i = 1; i < V; ++i) {
for (int j = 0; j < E; ++j) {
int u = graph.edge[j].src;
int v = graph.edge[j].dest;
int weight = graph.edge[j].weight;
if (dist[u] != Integer.MAX_VALUE && dist[u] + weight < dist[v])
dist[v] = dist[u] + weight;
}
}

// Check for negative-weight cycles
for (int j = 0; j < E; ++j) {
int u = graph.edge[j].src;
int v = graph.edge[j].dest;
int weight = graph.edge[j].weight;
if (dist[u] != Integer.MAX_VALUE && dist[u] + weight < dist[v]) {
System.out.println("Graph contains negative weight cycle");
return;
}
}

// Print the distance array
printArr(dist, V);
}

// Utility function to print the solution
void printArr(int dist[], int V) {
System.out.println("Vertex Distance from Source");
for (int i = 0; i < V; ++i)
System.out.println(i + "\t\t" + dist[i]);
}

}
```
Let’s see how the Bellman-Ford Algorithm can be implemented in C++:

Code in C++
```cpp
#include<bits/stdc++.h>
using namespace std;

struct Edge {
int src, dest, weight;
};

void bellmanFord(int V, int E, vector<Edge>& edges, int src) {
vector<int> dist(V, INT_MAX);
dist[src] = 0;

// Relax all edges V-1 times
for (int i = 1; i <= V - 1; i++) {
for (int j = 0; j < E; j++) {
int u = edges[j].src;
int v = edges[j].dest;
int weight = edges[j].weight;
if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) {
dist[v] = dist[u] + weight;
}
}
}

// Check for negative-weight cycles
for (int j = 0; j < E; j++) {
int u = edges[j].src;
int v = edges[j].dest;
int weight = edges[j].weight;
if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) {
cout << "Graph contains negative weight cycle" << endl;
return;
}
}

// Print the distance array
cout << "Vertex Distance from Source:" << endl;
for (int i = 0; i < V; i++)
cout << i << "\t\t" << dist[i] << endl;
}

int main() {
int V, E;
cin >> V >> E;

vector<Edge> edges(E);

for (int i = 0; i < E; i++) {
cin >> edges[i].src >> edges[i].dest >> edges[i].weight;
}

int src;
cin >> src;

bellmanFord(V, E, edges, src);

return 0;
}
```


## Time complexity:

Bellman-Ford Algorithm: O(V * E), where V is the number of vertices, and E is the number of edges.


## Points to Remember:

- The Bellman-Ford algorithm can handle graphs with negative weight edges.



- It detects negative weight cycles and reports if one exists.



- The algorithm is slower than Dijkstra’s, but it works with graphs that have negative weights.
Loading
Loading