Skip to content

Commit

Permalink
Merge branch 'neetcode-gh:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Vitali-Matteo authored Aug 22, 2022
2 parents 7fb3e8c + 3d15a8b commit 95eccc2
Show file tree
Hide file tree
Showing 177 changed files with 7,125 additions and 169 deletions.
35 changes: 18 additions & 17 deletions .github/workflows/updateCompletionTable.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
const { readdirSync } = require('fs');

const IGNORE_DIRS = ['.github', '.git'];
const PREPEND_PATH = process.argv[2] || './';
const FOLDER_TO_LANG = {
javascript: 'JS',
typescript: 'TS',
csharp: 'C#',
c: 'C',
go: 'GO',
java: 'Java',
python: 'Python',
ruby: 'Ruby',
rust: 'Rust',
scala: 'Scala',
swift: 'Swift',
cpp: 'C++',
kotlin: 'Kotlin'
};

const PROBLEM_LISTS = {
'NeetCode 150': [
['Contains Duplicate', '217'],
Expand Down Expand Up @@ -466,23 +484,6 @@ const URLS = {
};
delete URLS['Blind 75'];

const IGNORE_DIRS = ['.github', 'cpp', 'rust', '.git'];
const PREPEND_PATH = process.argv[2] || './';
const FOLDER_TO_LANG = {
javascript: 'JS',
typescript: 'TS',
csharp: 'C#',
c: 'C',
go: 'GO',
java: 'Java',
python: 'Python',
ruby: 'Ruby',
rust: 'Rust',
scala: 'Scala',
swift: 'Swift',
cpp: 'C++',
kotlin: 'Kotlin'
};

const getDirectories = (source) =>
readdirSync(source, { withFileTypes: true })
Expand Down
304 changes: 152 additions & 152 deletions README.md

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions c/704-Binary-Search.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Given an array of integers, search for a target value.
Examples:
nums = [-1,0,3,5,9,12], target = 9, return 4 (index of target 9)
nums = [-1,0,3,5,9,12], target = 2, return -1 (not found)
Array is sorted, so perform binary search
Time: O(log n)
Space: O(1)
*/

int search(int* nums, int numsSize, int target) {
int left = 0;
int right = numsSize-1;

while (left <= right) {
int mid = left + (right - left) / 2;

if (nums[mid] == target) {
return mid;
}
else if (nums[mid] < target) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
return -1;
}
30 changes: 30 additions & 0 deletions cpp/1-Two-Sum.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Given int array & target, return indices of 2 nums that add to target
Ex. nums = [2,7,11,15] & target = 9 -> [0,1], 2 + 7 = 9
At each num, calculate complement, if exists in hash map then return
Time: O(n)
Space: O(n)
*/

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
vector<int> result;

for (int i = 0; i < nums.size(); i++) {
int complement = target - nums[i];
if (m.find(complement) != m.end()) {
result.push_back(m[complement]);
result.push_back(i);
break;
} else {
m.insert({nums[i], i});
}
}

return result;
}
};
49 changes: 49 additions & 0 deletions cpp/10-Regular-Expression-Matching.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Given string & pattern, implement RegEx matching
'.' -> matches any single character
'*' -> matches zero or more of the preceding element
Matching should cover the entire input string (not partial)
Ex. s = "aa", p = "a" -> false, "a" doesn't match entire string "aa"
DFS + memo, 2 choices at a *: either use it, or don't use it
Time: O(m x n)
Space: O(m x n)
*/

class Solution {
public:
bool isMatch(string s, string p) {
return dfs(s, p, 0, 0);
}
private:
map<pair<int, int>, bool> dp;

bool dfs(string& s, string& p, int i, int j) {
if (dp.find({i, j}) != dp.end()) {
return dp[{i, j}];
}

if (i >= s.size() && j >= p.size()) {
return true;
}
if (j >= p.size()) {
return false;
}

bool match = i < s.size() && (s[i] == p[j] || p[j] == '.');
if (j + 1 < p.size() && p[j + 1] == '*') {
// choices: either (1) don't use *, or (2) use *
dp[{i, j}] = dfs(s, p, i, j + 2) || (match && dfs(s, p, i + 1, j));
return dp[{i, j}];
}

if (match) {
dp[{i, j}] = dfs(s, p, i + 1, j + 1);
return dp[{i, j}];
}

dp[{i, j}] = false;
return dp[{i, j}];
}
};
36 changes: 36 additions & 0 deletions cpp/100-Same-Tree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Given roots of 2 binary trees, check if they're the same or not (same structure & values)
Ex. p = [1,2,3] q = [1,2,3] -> true, p = [1,2] q = [1,null,2] -> false
Check: (1) matching nulls, (2) non-matching nulls, (3) non-matching values
Time: O(n)
Space: O(n)
*/

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == NULL && q == NULL) {
return true;
}
if (p == NULL || q == NULL) {
return false;
}
if (p->val != q->val) {
return false;
}
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
57 changes: 57 additions & 0 deletions cpp/102-Binary-Tree-Level-Order-Traversal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Given root of binary tree, return level order traversal of its nodes (left to right)
Ex. root = [3,9,20,null,null,15,7] -> [[3],[9,20],[15,7]]
Standard BFS traversal, at each level, push left & right nodes if they exist to queue
Time: O(n)
Space: O(n)
*/

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;

if (root == NULL) {
return result;
}

queue<TreeNode*> q;
q.push(root);

while (!q.empty()) {
int count = q.size();
vector<int> curr;

for (int i = 0; i < count; i++) {
TreeNode* node = q.front();
q.pop();

curr.push_back(node->val);

if (node->left != NULL) {
q.push(node->left);
}
if (node->right != NULL) {
q.push(node->right);
}
}

result.push_back(curr);
}

return result;
}
};
56 changes: 56 additions & 0 deletions cpp/104-Maximum-Depth-Of-Binary-Tree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
Given root of binary tree, return max depth (# nodes along longest path from root to leaf)
At every node, max depth is the max depth between its left & right children + 1
Time: O(n)
Space: O(n)
*/

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == NULL) {
return 0;
}
return 1 + max(maxDepth(root->left), maxDepth(root->right));
}
};

// class Solution {
// public:
// int maxDepth(TreeNode* root) {
// if (root == NULL) {
// return 0;
// }
// queue<TreeNode*> q;
// q.push(root);
// int result = 0;
// while (!q.empty()) {
// int count = q.size();
// for (int i = 0; i < count; i++) {
// TreeNode* node = q.front();
// q.pop();
// if (node->left != NULL) {
// q.push(node->left);
// }
// if (node->right != NULL) {
// q.push(node->right);
// }
// }
// result++;
// }
// return result;
// }
// };
35 changes: 35 additions & 0 deletions cpp/1046-Last-Stone-Weight.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Given array of stones to smash, return smallest possible weight of last stone
If x == y both stones destroyed, if x != y stone x destroyed, stone y = y - x
Ex. stones = [2,7,4,1,8,1] -> 1, [2,4,1,1,1], [2,1,1,1], [1,1,1], [1]
Max heap, pop 2 biggest, push back difference until no more 2 elements left
Time: O(n log n)
Space: O(n)
*/

class Solution {
public:
int lastStoneWeight(vector<int>& stones) {
priority_queue<int> pq;
for (int i = 0; i < stones.size(); i++) {
pq.push(stones[i]);
}

while (pq.size() > 1) {
int y = pq.top();
pq.pop();
int x = pq.top();
pq.pop();
if (y > x) {
pq.push(y - x);
}
}

if (pq.empty()) {
return 0;
}
return pq.top();
}
};
50 changes: 50 additions & 0 deletions cpp/105-Construct-Binary-Tree-From-Preorder-And-Inorder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Given 2 integer arrays preorder & inorder, construct & return the binary tree
Ex. preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] -> [3,9,20,null,null,15,7]
Preorder dictates nodes, inorder dictates subtrees (preorder values, inorder positions)
Time: O(n)
Space: O(n)
*/

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int index = 0;
return build(preorder, inorder, index, 0, inorder.size() - 1);
}
private:
TreeNode* build(vector<int>& preorder, vector<int>& inorder, int& index, int i, int j) {
if (i > j) {
return NULL;
}

TreeNode* root = new TreeNode(preorder[index]);

int split = 0;
for (int i = 0; i < inorder.size(); i++) {
if (preorder[index] == inorder[i]) {
split = i;
break;
}
}
index++;

root->left = build(preorder, inorder, index, i, split - 1);
root->right = build(preorder, inorder, index, split + 1, j);

return root;
}
};
Loading

0 comments on commit 95eccc2

Please sign in to comment.