From 7b04cd50fb7335d85db4e0c088bd33bd160f5643 Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Thu, 18 May 2023 13:30:24 +0000 Subject: [PATCH 01/11] Add a levelOrder4 in algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp --- .../binaryTreeLevelOrderTraversal.cpp | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp b/algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp index a5c1225c0..00ce240c1 100644 --- a/algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp +++ b/algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp @@ -182,6 +182,31 @@ vector > levelOrder3(TreeNode *root) { return vv; } +vector> levelOrder4(TreeNode *root) { + vector> result; + if (!root) return result; + queue q; + q.push(root); + while (q.size()> 0 ) + { /* cout< res{}; + while (count < length) + { + TreeNode* node = q.front(); + q.pop(); + res.push_back(node->val); + if(node->left) q.push(node->left); + if(node->right) q.push(node->right); + count += 1; + } + result.push_back(res); + } + return result; + +} + void printTree(TreeNode *root) { if (root == NULL){ From 099f944dc57b619d68bfdef2381127f9d88b5c2d Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Thu, 18 May 2023 15:50:17 +0000 Subject: [PATCH 02/11] The another way to solve algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.II.cpp --- .../binaryTreeRightSideView.II.cpp | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.II.cpp diff --git a/algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.II.cpp b/algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.II.cpp new file mode 100644 index 000000000..4550e4977 --- /dev/null +++ b/algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.II.cpp @@ -0,0 +1,181 @@ +// Source : https://leetcode.com/problems/binary-tree-right-side-view/ +// Author : David Lin +// Date : 2023-05-18 + +/********************************************************************************** + * + * Given a binary tree, imagine yourself standing on the right side of it, return + * the values of the nodes you can see ordered from top to bottom. + * + * For example: + * Given the following binary tree, + * + * 1 <--- + * / \ + * 2 3 <--- + * \ \ + * 5 4 <--- + * + * You should return [1, 3, 4]. + * + * + * + **********************************************************************************/ +#include +#include +#include +#include +#include +#include + +using namespace std; + + +struct TreeNode { + int val; + TreeNode *left; + TreeNode *right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} +}; + + +void printTree(TreeNode *root) +{ + if (root == NULL){ + printf("# "); + return; + } + printf("%d ", root->val ); + + printTree(root->left); + printTree(root->right); +} + + +void printTree_level_order(TreeNode *root) +{ + queue q; + q.push(root); + while (q.size()>0){ + TreeNode* n = q.front(); + q.pop(); + if (n==NULL){ + cout << "# "; + continue; + } + cout << n->val << " "; + q.push(n->left); + q.push(n->right); + } + cout << endl; +} + + +TreeNode* createTree(int a[], int n) +{ + if (n<=0) return NULL; + + TreeNode **tree = new TreeNode*[n]; + + for(int i=0; ileft = tree[pos++]; + if (posright = tree[pos++]; + } + } + } + return tree[0]; +} + + +void printMatrix(vector &vv) +{ cout << "["; + for(int i=0; i rightSideView(TreeNode *root) { + vector Results; + if(!root) return Results; + queue q; + q.push(root); + while (!q.empty()) + { + int length = q.size(); + int count{}; + while (count < length) + { + TreeNode* p = q.front(); + q.pop(); + if (count == length - 1) Results.push_back(p->val); + if(p->left) q.push(p->left); + if(p->right) q.push(p->right); + count += 1; + + } + + } + return Results; +} + + +void dfs(TreeNode* root, int level, vector& Result){ + if (level == Result.size()) { + Result.push_back(root->val); + } +/* printMatrix(Result); */ + if (root->right){ + dfs(root->right, level+1, Result); + } + if (root->left){ + dfs(root->left, level+1, Result); + } +} + + +vector rightSideView2(TreeNode *root){ + vector Result; + if(!root) return Result; + int level; + dfs(root, level, Result); + /* printMatrix(Result); */ + return Result; + +} + + +int main() +{ + TreeNode *p; + vector vv; + + int a[] = {1,2,3,0,5,0,4}; + p = createTree(a, sizeof(a)/sizeof(int)); + printTree_level_order(p); + vv = rightSideView(p); + printMatrix(vv); + cout << endl; + + int b[] = {1,2,3,0,5,0,4}; + p = createTree(b, sizeof(b)/sizeof(int)); + printTree_level_order(p); + vv = rightSideView2(p); + printMatrix(vv); + cout << endl; +} \ No newline at end of file From cf8a73df6ad1850d4d42e4b643c7195201e415ee Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Thu, 18 May 2023 15:57:52 +0000 Subject: [PATCH 03/11] The another way to solve algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.II.cpp --- .../CountCompleteTreeNodes.II.cpp | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.II.cpp diff --git a/algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.II.cpp b/algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.II.cpp new file mode 100644 index 000000000..100549218 --- /dev/null +++ b/algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.II.cpp @@ -0,0 +1,209 @@ +// Source : https://leetcode.com/problems/count-complete-tree-nodes/ +// Author : David Lin +// Date : 2023-05-18 + +/********************************************************************************** + * + * Given a complete binary tree, count the number of nodes. + * + * Definition of a complete binary tree from Wikipedia: + * http://en.wikipedia.org/wiki/Binary_tree#Types_of_binary_trees + * + * In a complete binary tree every level, except possibly the last, is completely filled, + * and all nodes in the last level are as far left as possible. + * It can have between 1 and 2^h nodes inclusive at the last level h. + * + **********************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + + +using namespace std; + + +struct TreeNode { + int val; + TreeNode *left; + TreeNode *right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} +}; + + +void printTree(TreeNode *root) +{ + if (root == NULL){ + printf("# "); + return; + } + printf("%d ", root->val ); + + printTree(root->left); + printTree(root->right); +} + + +void printTree_level_order(TreeNode *root) +{ + queue q; + q.push(root); + while (q.size()>0){ + TreeNode* n = q.front(); + q.pop(); + if (n==NULL){ + cout << "# "; + continue; + } + cout << n->val << " "; + q.push(n->left); + q.push(n->right); + } + cout << endl; +} + + +TreeNode* createTree(int a[], int n) +{ + if (n<=0) return NULL; + + TreeNode **tree = new TreeNode*[n]; + + for(int i=0; ileft = tree[pos++]; + if (posright = tree[pos++]; + } + } + } + return tree[0]; +} + + +void printMatrix(vector &vv) +{ cout << "["; + for(int i=0; ileft, right=right->right) { + cnt *= 2; + } + + if (left!=NULL || right!=NULL) { + return -1; + } + return cnt-1; + } + + int countNodes(TreeNode* root) { + int cnt = isCompleteTree(root); + if (cnt != -1) return cnt; + int leftCnt = countNodes(root->left); + int rightCnt = countNodes(root->right); + return leftCnt + rightCnt + 1; + } +}; + + +class Solution2 { +public: + int GetHeight(TreeNode* root){ + int height = 0; + while (root->left) + { + height++; + root = root->left; + } + return height; + } + + + bool IsNodeExist(int idx_to_find, int height, TreeNode* root){ + int left = 0; + int right = pow(2, height) - 1; + while (left= middle_idx) + { + root = root->right; + left = middle_idx; + }else{ + root = root->left; + right = middle_idx - 1; + } + } + return root != NULL; + + } + + + int countNodes(TreeNode* root) { + if (!root) return 0; + int height = GetHeight(root); + int uppercount = pow(2, height) - 1; + int left = 0; + int right = uppercount; + while (left < right) + { + int idx_to_find = ceil(float(left+right)/2); + if(IsNodeExist(idx_to_find, height, root)){ + left = idx_to_find; + }else{ + right = idx_to_find-1; + } + } + return uppercount + right + 1; + + } +}; + +int main() +{ + TreeNode *p; + int vv; + Solution s = Solution(); + + + int a[] = {1,2,3,0,5,0,4}; + p = createTree(a, sizeof(a)/sizeof(int)); + printTree_level_order(p); + vv = s.countNodes(p); + cout << vv < Date: Sat, 20 May 2023 03:13:28 +0000 Subject: [PATCH 04/11] Add c++ solution at algorithms/cpp/rottingOranges/rottingOranges.cpp --- .../cpp/rottingOranges/rottingOranges.cpp | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 algorithms/cpp/rottingOranges/rottingOranges.cpp diff --git a/algorithms/cpp/rottingOranges/rottingOranges.cpp b/algorithms/cpp/rottingOranges/rottingOranges.cpp new file mode 100644 index 000000000..c80bad161 --- /dev/null +++ b/algorithms/cpp/rottingOranges/rottingOranges.cpp @@ -0,0 +1,119 @@ +// Source : https://leetcode.com/problems/rotting-oranges/ +// Author : David Lin +// Date : 2023-05-18 + +/********************************************************************************** + * +You are given an m x n grid where each cell can have one of three values: + +0 representing an empty cell, +1 representing a fresh orange, or +2 representing a rotten orange. +Every minute, any fresh orange that is 4-directionally adjacent to a rotten orange becomes rotten. + +Return the minimum number of minutes that must elapse until no cell has a fresh orange. If this is impossible, return -1. + * + * Example 1: + * 211 + * 110 + * 011 + * Answer: 4 + * + * Example 2: + * 211 + * 011 + * 101 + * Answer: -1 + * + * Example 3: + * 02 + * Answer: 0 + * + * + * + **********************************************************************************/ + +#include +#include +#include +#include + +using namespace std; + + +int orangesRotting(vector >& grid) { + int minutes{}; + int num_fresh{}; + queue> q; + int row_size = grid.size(); + int col_size = grid[0].size(); + for(int row{}; row < row_size; row++){ + for(int col{}; col< col_size; col++){ + switch (grid[row][col]) + { + case 2: + q.push({row, col}); + break; + case 1: + num_fresh++; + break; + default: + break; + } + } + } + + vector> directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + int q_size = q.size(); + if (q_size == 0){ + if (num_fresh == 0)return 0; + return -1; + } + + while (!q.empty()) + { + if(q_size == 0 && q.size() > 0){ + minutes++; + q_size = q.size(); + } + int row = q.front().first; + int col = q.front().second; + q.pop(); + + for(auto& direction: directions){ + int new_row = row + direction.first; + int new_col = col + direction.second; + if(new_row < row_size && new_row >= 0 && new_col < col_size && new_col >= 0){ + if(grid[new_row][new_col] == 1){ + grid[new_row][new_col] = 2; + q.push({new_row, new_col}); + num_fresh--; + } + } + } + q_size--; + } + if(num_fresh > 0)return -1; + return minutes; +} + + +int main(void) +{ + vector< vector > grid; + grid.push_back( vector(1, 0) ); + cout << orangesRotting(grid) << endl; + grid.clear(); + + grid = {{2,1,1},{1,1,0},{0,1,1}}; + cout << orangesRotting(grid) << endl; + grid.clear(); + + grid = {{2,1,1},{0,1,1},{1,0,1}}; + cout << orangesRotting(grid) << endl; + grid.clear(); + + grid = {{0,2}}; + cout << orangesRotting(grid) << endl; + return 0; +} From aa1f357ab3ed2160895bb9f6b7e63c775b677550 Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Sat, 20 May 2023 10:58:56 +0000 Subject: [PATCH 05/11] Add c++ solution for wallAndGates --- algorithms/cpp/wallAndGates/wallAndGates.cpp | 85 ++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 algorithms/cpp/wallAndGates/wallAndGates.cpp diff --git a/algorithms/cpp/wallAndGates/wallAndGates.cpp b/algorithms/cpp/wallAndGates/wallAndGates.cpp new file mode 100644 index 000000000..1306cdc35 --- /dev/null +++ b/algorithms/cpp/wallAndGates/wallAndGates.cpp @@ -0,0 +1,85 @@ +// Source : https://leetcode.com/problems/walls-and-gates/ +// Author : David Lin +// Date : 2023-05-20 + +/********************************************************************************** + * +You are given a m x n 2D grid initialized with these three possible values. + +-1 - A wall or an obstacle. +0 - A gate. +INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than 2147483647. +Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF. + * +For example, given the 2D grid: +INF -1 0 INF +INF INF INF -1 +INF -1 INF -1 + 0 -1 INF INF +After running your function, the 2D grid should be: + 3 -1 0 1 + 2 2 1 -1 + 1 -1 2 -1 + 0 -1 3 4 + * + * + * + **********************************************************************************/ + +#include +#include +#include +#include + +#define INF 2147483647 + +using namespace std; + + +void dfs(vector>& grid, int row, int col, vector>& directions, int current_steps){ + + if(row < 0 || col < 0 || row >= grid.size() || col >= grid[0].size() || current_steps > grid[row][col] ) return; + + grid[row][col] = current_steps; + + for(auto& direction: directions){ + dfs(grid, row + direction.first, col + direction.second, directions, current_steps+1); + } +} + +vector>& wallAndGates(vector>& grid) { + vector> directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + for(int row{}; row < grid.size(); row++){ + for(int col{}; col < grid[0].size(); col++){ + if(grid[row][col] == 0){ + dfs(grid, row, col, directions, 0); + } + } + } + return grid; + +} + +int printMatrix(vector< vector > &vv) +{ + for(int i=0; i > grid; + grid = {{INF, -1, 0, INF}, + {INF, INF, INF, -1}, + {INF, -1, INF, -1}, + {0, -1, INF, INF}}; + printMatrix(wallAndGates(grid)); + + return 0; +} From 3c66de8a01cb6167326e8fed45d6f9693dccf3c7 Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Mon, 22 May 2023 13:34:31 +0000 Subject: [PATCH 06/11] The second C++ solution for the problem in algorithms/cpp/timeNeededToInformAllEmployees/TimeNeededToInformAllEmployees.II.cpp --- .../TimeNeededToInformAllEmployees.II.cpp | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 algorithms/cpp/timeNeededToInformAllEmployees/TimeNeededToInformAllEmployees.II.cpp diff --git a/algorithms/cpp/timeNeededToInformAllEmployees/TimeNeededToInformAllEmployees.II.cpp b/algorithms/cpp/timeNeededToInformAllEmployees/TimeNeededToInformAllEmployees.II.cpp new file mode 100644 index 000000000..ffb589551 --- /dev/null +++ b/algorithms/cpp/timeNeededToInformAllEmployees/TimeNeededToInformAllEmployees.II.cpp @@ -0,0 +1,64 @@ +// Source : https://leetcode.com/problems/time-needed-to-inform-all-employees/ +// Author : David Lin +// Date : 2023-05-22 + +/*************************************************************************************** + * + * A company has n employees with a unique ID for each employee from 0 to n - 1. + * The head of the company has is the one with headID. + * + * Each employee has one direct manager given in the manager array where manager[i] is + * the direct manager of the i-th employee, manager[headID] = -1. Also it's guaranteed + * that the subordination relationships have a tree structure. + * + * The head of the company wants to inform all the employees of the company of an urgent + * piece of news. He will inform his direct subordinates and they will inform their + * subordinates and so on until all employees know about the urgent news. + * + * The i-th employee needs informTime[i] minutes to inform all of his direct subordinates + * (i.e After informTime[i] minutes, all his direct subordinates can start spreading the news). + * + * Return the number of minutes needed to inform all the employees about the urgent news. + * + * Example: + * + * Given: n = 1, headID = 0, manager = [-1], informTime = [0] + * Return: 0 + * + * Given: n = 7, headID = 6, manager = [1,2,3,4,5,6,-1], informTime = [0,6,5,4,3,2,1] + * Return: 21 + * + ***************************************************************************************/ +# include +# include + +using namespace std; + +void dfs(vector>& adjlist, int head, vector& informTime){ + + if(adjlist[head].empty()){ + return; + } + int max_inform_time = -1; + for(auto& employee: adjlist[head]){ + dfs(adjlist, employee, informTime); + if(informTime[employee] > max_inform_time){ + max_inform_time = informTime[employee]; + } + } + informTime[head] = informTime[head] + max_inform_time; +} + + + +int numOfMinutes(int n, int headID, vector& manager, vector& informTime) { + + vector> adjlist(n+1); + for(int i{}; i < n; i++){ + if(manager[i] == -1)continue; + adjlist.at(manager[i]).push_back(i); + } + dfs(adjlist, headID, informTime); + + return informTime[headID]; +} From d28b6b5b72d32a7686d117cd06f50c2e64a7e9f8 Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Mon, 5 Jun 2023 14:24:30 +0000 Subject: [PATCH 07/11] add C++ solution in algorithms/cpp/courseSchedule/SunnyLin/ --- .../binaryTreeLevelOrderTraversal.cpp | 4 +- .../binaryTreeRightSideView.II.cpp | 2 +- .../CountCompleteTreeNodes.II.cpp | 2 +- .../SunnyLin/CourseSchedule.II.cpp | 87 ++++++++++++++ .../SunnyLin/CourseSchedule.cpp | 106 ++++++++++++++++++ .../numberOfIslands/NumberOfIslands.II.cpp | 104 +++++++++++++++++ .../cpp/rottingOranges/rottingOranges.cpp | 2 +- .../TimeNeededToInformAllEmployees.II.cpp | 2 +- algorithms/cpp/wallAndGates/wallAndGates.cpp | 2 +- 9 files changed, 304 insertions(+), 7 deletions(-) create mode 100644 algorithms/cpp/courseSchedule/SunnyLin/CourseSchedule.II.cpp create mode 100644 algorithms/cpp/courseSchedule/SunnyLin/CourseSchedule.cpp create mode 100644 algorithms/cpp/numberOfIslands/NumberOfIslands.II.cpp diff --git a/algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp b/algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp index 00ce240c1..829e6c4cb 100644 --- a/algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp +++ b/algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp @@ -1,6 +1,6 @@ // Source : https://oj.leetcode.com/problems/binary-tree-level-order-traversal/ -// Author : Hao Chen -// Date : 2014-07-17 +// Author : Hao Chen, Sunny Lin +// Date : 2023-06-05 /********************************************************************************** * diff --git a/algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.II.cpp b/algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.II.cpp index 4550e4977..8e5614f3b 100644 --- a/algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.II.cpp +++ b/algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.II.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/binary-tree-right-side-view/ -// Author : David Lin +// Author : Sunny Lin // Date : 2023-05-18 /********************************************************************************** diff --git a/algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.II.cpp b/algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.II.cpp index 100549218..7be96634f 100644 --- a/algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.II.cpp +++ b/algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.II.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/count-complete-tree-nodes/ -// Author : David Lin +// Author : Sunny Lin // Date : 2023-05-18 /********************************************************************************** diff --git a/algorithms/cpp/courseSchedule/SunnyLin/CourseSchedule.II.cpp b/algorithms/cpp/courseSchedule/SunnyLin/CourseSchedule.II.cpp new file mode 100644 index 000000000..fad2c5562 --- /dev/null +++ b/algorithms/cpp/courseSchedule/SunnyLin/CourseSchedule.II.cpp @@ -0,0 +1,87 @@ +// Source : https://leetcode.com/problems/course-schedule/ +// Author : Sunny Lin +// Date : 2023-06-05 + +/********************************************************************************** + * + * There are a total of n courses you have to take, labeled from 0 to n - 1. + * + * Some courses may have prerequisites, for example to take course 0 you have to first take course 1, + * which is expressed as a pair: [0,1] + * + * Given the total number of courses and a list of prerequisite pairs, return the ordering of courses + * you should take to finish all courses. + * + * There may be multiple correct orders, you just need to return one of them. If it is impossible to + * finish all courses, return an empty array. + * + * For example: + * 2, [[1,0]] + * There are a total of 2 courses to take. To take course 1 you should have finished course 0. + * So the correct course order is [0,1] + * + * 4, [[1,0],[2,0],[3,1],[3,2]] + * There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. + * Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. + * Another correct ordering is[0,2,1,3]. + * + * Note: + * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. + * Read more about how a graph is represented. + * + * click to show more hints. + * + * Hints: + * + * - This problem is equivalent to finding the topological order in a directed graph. If a cycle exists, + * no topological ordering exists and therefore it will be impossible to take all courses. + * + * - Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining + * the basic concepts of Topological Sort. + * + * - Topological sort could also be done via BFS. + * + * + **********************************************************************************/ + +#include + +#include +#include +using std::stack; +using std::vector; +using std::pair; + +bool canFinish(int numCourses, vector>& prerequisites) { + vector> adjlist(numCourses); + vector indegree(numCourses, 0); + + for(auto& pair: prerequisites){ + adjlist[pair[1]].push_back(pair[0]); + indegree[pair[0]]++; + } + + stack stack; + for(int i{}; i < indegree.size(); i++){ + if(indegree[i] == 0){ + stack.push(i); + } + } + + int count{}; + while (!stack.empty()) + { + int topo_index = stack.top(); + stack.pop(); + count++; + + for(auto& item: adjlist[topo_index]){ + indegree[item]--; + if(indegree[item] == 0){ + stack.push(item); + } + } + } + if(count != numCourses) return false; + return true; +} \ No newline at end of file diff --git a/algorithms/cpp/courseSchedule/SunnyLin/CourseSchedule.cpp b/algorithms/cpp/courseSchedule/SunnyLin/CourseSchedule.cpp new file mode 100644 index 000000000..1a266da50 --- /dev/null +++ b/algorithms/cpp/courseSchedule/SunnyLin/CourseSchedule.cpp @@ -0,0 +1,106 @@ +// Source : https://leetcode.com/problems/course-schedule/ +// Author : Sunny Lin +// Date : 2023-06-05 + +/********************************************************************************** + * + * There are a total of n courses you have to take, labeled from 0 to n - 1. + * + * Some courses may have prerequisites, for example to take course 0 you have to first take course 1, + * which is expressed as a pair: [0,1] + * + * Given the total number of courses and a list of prerequisite pairs, return the ordering of courses + * you should take to finish all courses. + * + * There may be multiple correct orders, you just need to return one of them. If it is impossible to + * finish all courses, return an empty array. + * + * For example: + * 2, [[1,0]] + * There are a total of 2 courses to take. To take course 1 you should have finished course 0. + * So the correct course order is [0,1] + * + * 4, [[1,0],[2,0],[3,1],[3,2]] + * There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. + * Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. + * Another correct ordering is[0,2,1,3]. + * + * Note: + * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. + * Read more about how a graph is represented. + * + * click to show more hints. + * + * Hints: + * + * - This problem is equivalent to finding the topological order in a directed graph. If a cycle exists, + * no topological ordering exists and therefore it will be impossible to take all courses. + * + * - Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining + * the basic concepts of Topological Sort. + * + * - Topological sort could also be done via BFS. + * + * + **********************************************************************************/ + +#include + +#include +#include +#include + +using std::queue; +using std::vector; +using std::pair; + +bool dfs(int head, vector>& adjlist, vector& seen){ + + if (seen[head] == false){ + seen[head] = true; + } + else{ + return false; + } + + for(auto& adj: adjlist[head]){ + + if( not dfs(adj, adjlist, seen)){ + return false; + } + } + return true; + +} + + +bool canFinish(int numCourses, vector>& prerequisites) { + vector> adjlist(numCourses); + int current{}; + + queue q; + for(auto& pair: prerequisites){ + adjlist[pair[1]].push_back(pair[0]); + } + + for(int v{}; v < adjlist[v].size(); v++){ + vector seen(numCourses, false); + for(auto& adj_v : adjlist[v]){ + q.push(adj_v); + } + + while (!q.empty()) + { + current = q.front(); + if(current == v)return false; + q.pop(); + seen[current] = true; + for(auto& adj_current: adjlist[current]){ + if(~seen[adj_current]){ + q.push(adj_current); + } + } + } + } + return true; +} \ No newline at end of file diff --git a/algorithms/cpp/numberOfIslands/NumberOfIslands.II.cpp b/algorithms/cpp/numberOfIslands/NumberOfIslands.II.cpp new file mode 100644 index 000000000..7b6735825 --- /dev/null +++ b/algorithms/cpp/numberOfIslands/NumberOfIslands.II.cpp @@ -0,0 +1,104 @@ +// Source : https://leetcode.com/problems/number-of-islands/ +// Author : David Lin +// Date : 2023-05-20 + +/********************************************************************************** + * + * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. + * An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. + * You may assume all four edges of the grid are all surrounded by water. + * + * Example 1: + * 11110 + * 11010 + * 11000 + * 00000 + * Answer: 1 + * + * Example 2: + * 11000 + * 11000 + * 00100 + * 00011 + * Answer: 3 + * + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. + * + **********************************************************************************/ + +#include +#include +using namespace std; + +void dfs(vector >& grid, int row, int col, int row_boarder, int col_boarder){ + + if (row < 0 + || col < 0 + || row >= row_boarder + || col >= col_boarder + || grid[row][col]=='0') return; + grid[row][col] = '0'; + + + dfs(grid, row + 1, col, row_boarder, col_boarder); + dfs(grid, row, col + 1, row_boarder, col_boarder); + dfs(grid, row, col - 1, row_boarder, col_boarder); + dfs(grid, row -1, col, row_boarder, col_boarder); +} + +int numIslands(vector >& grid) { + if (grid.size()== 0) return 0; + int count = 0; + int row_boarder = grid.size(); + int col_boarder = grid[0].size(); + for (int row = 0; row < grid.size(); row++){ + for (int col = 0; col < grid[0].size(); col++){ + if (grid[row][col] == '1'){ + count++; + dfs(grid, row, col, row_boarder, col_boarder); + } + } + } + return count; +} + +void initGrid( string g[], int len, vector >& grid ) +{ + for (int i=0; i(g[i].begin(), g[i].end())); + } +} + +int main(void) +{ + vector< vector > grid; + grid.push_back( vector(1, '1') ); + + cout << numIslands(grid) << endl; + + + grid.clear(); + + string g1[] = { "11110", + "11010", + "11000", + "00000" }; + + initGrid(g1, 4, grid); + cout << numIslands(grid) << endl; + + + + grid.clear(); + + string g2[] = { "11000", + "11000", + "00100", + "00011" }; + + initGrid(g2, 4, grid); + cout << numIslands(grid) << endl; + + + return 0; +} diff --git a/algorithms/cpp/rottingOranges/rottingOranges.cpp b/algorithms/cpp/rottingOranges/rottingOranges.cpp index c80bad161..2adc3abda 100644 --- a/algorithms/cpp/rottingOranges/rottingOranges.cpp +++ b/algorithms/cpp/rottingOranges/rottingOranges.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/rotting-oranges/ -// Author : David Lin +// Author : Sunny Lin // Date : 2023-05-18 /********************************************************************************** diff --git a/algorithms/cpp/timeNeededToInformAllEmployees/TimeNeededToInformAllEmployees.II.cpp b/algorithms/cpp/timeNeededToInformAllEmployees/TimeNeededToInformAllEmployees.II.cpp index ffb589551..8dedc5fa8 100644 --- a/algorithms/cpp/timeNeededToInformAllEmployees/TimeNeededToInformAllEmployees.II.cpp +++ b/algorithms/cpp/timeNeededToInformAllEmployees/TimeNeededToInformAllEmployees.II.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/time-needed-to-inform-all-employees/ -// Author : David Lin +// Author : Sunny Lin // Date : 2023-05-22 /*************************************************************************************** diff --git a/algorithms/cpp/wallAndGates/wallAndGates.cpp b/algorithms/cpp/wallAndGates/wallAndGates.cpp index 1306cdc35..f12a4d1eb 100644 --- a/algorithms/cpp/wallAndGates/wallAndGates.cpp +++ b/algorithms/cpp/wallAndGates/wallAndGates.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/walls-and-gates/ -// Author : David Lin +// Author : Sunny Lin // Date : 2023-05-20 /********************************************************************************** From eab6201a68aa7abc7ab81cd4fa1f01b7dd4181a8 Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:34:58 +0000 Subject: [PATCH 08/11] add c++ new solution in algorithms/cpp/knightProbabilityInChessboard/knightProbabilityInChessboard.cpp --- .../knightProbabilityInChessboard.cpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 algorithms/cpp/knightProbabilityInChessboard/knightProbabilityInChessboard.cpp diff --git a/algorithms/cpp/knightProbabilityInChessboard/knightProbabilityInChessboard.cpp b/algorithms/cpp/knightProbabilityInChessboard/knightProbabilityInChessboard.cpp new file mode 100644 index 000000000..d1fcbc8cc --- /dev/null +++ b/algorithms/cpp/knightProbabilityInChessboard/knightProbabilityInChessboard.cpp @@ -0,0 +1,43 @@ +// Source : https://leetcode.com/problems/knight-probability-in-chessboard/ +// Author : Sunny Lin +// Date : 2023-06-12 + +/***************************************************************************************************** + * + *On an n x n chessboard, a knight starts at the cell (row, column) and attempts to make exactly k moves. The rows and columns are 0-indexed, so the top-left cell is (0, 0), and the bottom-right cell is (n - 1, n - 1). + * + *A chess knight has eight possible moves it can make, as illustrated below. Each move is two cells in a cardinal direction, then one cell in an orthogonal direction. + * + * + *Each time the knight is to move, it chooses one of eight possible moves uniformly at random (even if the piece would go off the chessboard) and moves there. + * + *The knight continues moving until it has made exactly k moves or has moved off the chessboard. + * + *Return the probability that the knight remains on the board after it has stopped moving. + * + ******************************************************************************************************/ +#include +using namespace std; + +class Solution { + public: + + double Probability(int n, int i, int current_row, int current_column, vector>& directions, vector>>& dp){ + if(current_row < 0 or current_row >= n or current_column < 0 or current_column >= n){ + return 0.0; + } + if (i == 0) return 1.0; + if (dp[i][current_row][current_column]!= NULL) return dp[i][current_row][current_column]; + + for(auto& direction: directions){ + dp[i][current_row][current_column] += Probability(n, i-1, current_row + direction.first, current_column + direction.second, directions, dp)/8.0; + } + return dp[i][current_row][current_column]; + } + + double knightProbability(int n, int k, int row, int column) { + vector>>dp(k+1, vector>(n, vector(n, NULL))); + vector>directions{{-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {1, -2}, {2, -1}, {-2, -1}, {-1, -2}}; + return Probability(n, k, row, column, directions, dp); + } +}; From 85be23e9c02685610389dff8d15ab796b5cc3715 Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:38:37 +0000 Subject: [PATCH 09/11] add c++ solution (Dijkstra's algorithm) in algorithms/cpp/networkDelayTime/networkDelayTime.cpp --- .../cpp/networkDelayTime/networkDelayTime.cpp | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 algorithms/cpp/networkDelayTime/networkDelayTime.cpp diff --git a/algorithms/cpp/networkDelayTime/networkDelayTime.cpp b/algorithms/cpp/networkDelayTime/networkDelayTime.cpp new file mode 100644 index 000000000..25a196fd3 --- /dev/null +++ b/algorithms/cpp/networkDelayTime/networkDelayTime.cpp @@ -0,0 +1,59 @@ +// Source : https://leetcode.com/problems/network-delay-time/ +// Author : Sunny Lin +// Date : 2023-06-07 + +/********************************************************************************** +* +Utilize Dijkstra's algorithm + */ + +#include +#include + +#include +#include +#include +#include +#include +using namespace std; + +#define INF numeric_limits::max() + +struct cmp +{ + bool operator()(paira, pairb){ + return a.second > b.second; + } +}; + +int networkDelayTime(vector>& times, int n, int k) { + + vector>> adjlist(n); + for(auto & time: times){ + adjlist[time[0] - 1].push_back({time[1] - 1, time[2]}); + } + + vector _distance(n, INF); + _distance[k - 1] = 0; + + priority_queue, vector>, cmp>q; + q.push({k - 1, 0}); + + while (!q.empty()) + { + int current_vertex = q.top().first; + q.pop(); + for(auto& adj_neighbor: adjlist[current_vertex]){ + int neighboring_vertex = adj_neighbor.first; + int weight = adj_neighbor.second; + if(_distance[neighboring_vertex] > ( _distance[current_vertex] + weight)){ + _distance[neighboring_vertex] = _distance[current_vertex] + weight; + q.push({neighboring_vertex, _distance[neighboring_vertex]}); + } + } + } + int min_time = *max_element(_distance.begin(), _distance.end()); + if(min_time == INF) return -1; + return min_time; +} + From 21d11df23f6142235afcfc60c79ca81065f88a57 Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:40:39 +0000 Subject: [PATCH 10/11] add c++ solution (Bellman-Ford algorithm) in algorithms/cpp/networkDelayTime/networkDelayTime2.cpp --- .../networkDelayTime/networkDelayTime2.cpp | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 algorithms/cpp/networkDelayTime/networkDelayTime2.cpp diff --git a/algorithms/cpp/networkDelayTime/networkDelayTime2.cpp b/algorithms/cpp/networkDelayTime/networkDelayTime2.cpp new file mode 100644 index 000000000..8f81cf107 --- /dev/null +++ b/algorithms/cpp/networkDelayTime/networkDelayTime2.cpp @@ -0,0 +1,42 @@ +// Source : https://leetcode.com/problems/network-delay-time/ +// Author : Sunny Lin +// Date : 2023-06-07 + +/********************************************************************************** +* +Utilize Bellman-Ford algorithm + */ + +#include +#include + +#include +#include +#include +#include +#include +using namespace std; + +#define INF numeric_limits::max() + +int networkDelayTime(vector>& times, int n, int k) { + + vector _distance(n, INF); + _distance[k - 1] = 0; + + for(int i{}; i < n-1; i++){ + for(auto & source_target_time :times){ + int source = source_target_time[0]; + int target = source_target_time[1]; + int weight = source_target_time[2]; + if(_distance[source - 1] != INF and _distance[target -1] > _distance[source -1] + weight){ + _distance[target - 1] = _distance[source -1] + weight; + } + } + } + + int min_time = *max_element(_distance.begin(), _distance.end()); + if(min_time == INF) return -1; + return min_time; +} + From 9f2171e45175402f432f2fa965a2e0d6a16491f3 Mon Sep 17 00:00:00 2001 From: "LIN, YU-KAI" <83336281+yukailin-git@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:43:12 +0000 Subject: [PATCH 11/11] add c++ solution in algorithms/cpp/minCostClimbingStairs/MinCostClimbingStairs2.cpp --- .../MinCostClimbingStairs2.cpp | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 algorithms/cpp/minCostClimbingStairs/MinCostClimbingStairs2.cpp diff --git a/algorithms/cpp/minCostClimbingStairs/MinCostClimbingStairs2.cpp b/algorithms/cpp/minCostClimbingStairs/MinCostClimbingStairs2.cpp new file mode 100644 index 000000000..1ec338f01 --- /dev/null +++ b/algorithms/cpp/minCostClimbingStairs/MinCostClimbingStairs2.cpp @@ -0,0 +1,51 @@ +// Source : https://leetcode.com/problems/min-cost-climbing-stairs/ +// Author : Sunny Lin +// Date : 2023-06-12 + +/***************************************************************************************************** + * + * + * On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). + * + * Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to + * reach the top of the floor, and you can either start from the step with index 0, or the step with + * index 1. + * + * Example 1: + * + * Input: cost = [10, 15, 20] + * Output: 15 + * Explanation: Cheapest is start on cost[1], pay that cost and go to the top. + * + * Example 2: + * + * Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] + * Output: 6 + * Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3]. + * + * Note: + * + * cost will have a length in the range [2, 1000]. + * Every cost[i] will be an integer in the range [0, 999]. + * + ******************************************************************************************************/ +#include +using namespace std; + +class Solution { + public: + int minCost(int i, vector & cost, vector& dp){ + if(i < 0) return 0; + if(i == 0 or i == 1) return cost[i]; + if(dp[i] != NULL) return dp[i]; + dp[i] = cost[i] + min(minCost(i-1, cost, dp), minCost(i-2, cost, dp)); + return dp[i]; + } + + int minCostClimbingStairs(vector& cost) { + int n = cost.size(); + vector dp(n); + return min(minCost(n-1, cost, dp), minCost(n-2, cost, dp)); + } + +};