Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions C++/Cherry-Pickup-II.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class Solution {
private:
// Let's run a simple dfs. If we come to the same cell with two robots, let's subtract that value.
int dfs(int n, int m, int r, int c1, int c2, unordered_map<pair<int, pair<int, int>>, int> &dp, vector<vector<int>> &grid) {
if (c1 < 0 || c1 >= m || c2 < 0 || c2 >= m) {
return 0;
} else if (r == n) {
return 0;
} else if (dp.count({r, {c1, c2}}) > 0) {
return dp[{r, {c1, c2}}];
} else {
int current_ceil = grid[r][c1] + grid[r][c2];

// Here is that subtraction
if (c1 == c2) {
current_ceil -= grid[r][c2];
}

// Running dfs from all possible cells
int mx = 0;
for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
mx = max(mx, dfs(n, m, r + 1, c1 + i, c2 + j, dp, grid));
}
}

return dp[{r, {c1, c2}}] = current_ceil + mx;
}
}
public:
int cherryPickup(vector<vector<int>>& grid) {
unordered_map<pair<int, pair<int, int>>, int> dp;

int n = grid.size();
int m = grid[0].size();

return dfs(n, m, 0, 0, m - 1, dp, grid);
}
};
104 changes: 104 additions & 0 deletions C++/LRU-Cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Here I am using a hashmap to store a node pointer by a key. It will give us O(1) for all operations.
class LRUCache {
private:
struct Node {
Node *left = nullptr;
Node *right = nullptr;

int key;
int value;

Node(int key, int value) : key(key), value(value) {}
};

Node *root = nullptr;

Node *tail = nullptr;

unordered_map<int, Node*> hashmap;

int capacity;

void update_root(Node *node) {
Node *tmp = root;
if (tail == nullptr) {
tail = node;
} else if (tail == node) {
tail = node;

if (node->left != nullptr) {
tail = node->left;
}
}

if (root == nullptr) {
root = node;
tmp = root;
return;
}

if (root != node) {
Node *t = node->left;
if (t != nullptr) {
t->right = node->right;
if (node->right != nullptr) {
node->right->left = t;
}
}

node->right = root;
root->left = node;
root = node;
}
}

public:
LRUCache(int capacity) : capacity(capacity) {}

int get(int key) {
if (hashmap.count(key) == 0) {
return -1;
} else {
Node *node = hashmap[key];

update_root(node);

return root->value;
}
}

void put(int key, int value) {
if ((int) hashmap.size() == capacity && hashmap.count(key) == 0) {
hashmap.erase(tail->key);
Node *new_tail = nullptr;
if (tail->left != nullptr) {
new_tail = tail->left;
}
tail->left = nullptr;
tail = nullptr;

tail = new_tail;
if (tail != nullptr) {
tail->right = nullptr;
}
}

Node *node;
if (hashmap.count(key) == 0) {
node = new Node(key, value);
} else {
node = hashmap[key];
}
node->value = value;

hashmap[key] = node;
update_root(node);
}
};

/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// The main algorithm in this problem is Breadth First Search.
class Solution {
private:
bool valid(int n, int m, int x, int y) {
return (0 <= x && x < n) && (0 <= y && y < m);
}

string convert(vector<vector<int>> &c, int n, int m) {
string s;

for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
s += c[i][j] + '0';
}
}

return s;
}

int get(string s, int i, int j, int n, int m) {
return s[i * m + j] - '0';
}

void set(string &s, int i, int j, int val, int n, int m) {
s[i * m + j] = val + '0';
}

public:
int minFlips(vector<vector<int>>& c) {
int n = c.size();
int m = c[0].size();

map<string, int> dp;
map<string, bool> used;

vector<int> dx = {-1, 0, 1, 0};
vector<int> dy = {0, 1, 0, -1};

string cToNum = convert(c, n, m);
string zero(n * m, '0');

if (cToNum == zero) {
return 0;
}

queue<string> q;
q.push(cToNum);

dp[cToNum] = 0;

while (!q.empty()) {
string a = q.front();
q.pop();

used[a] = true;

for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
string b = a;

set(b, i, j, 1 - get(b, i, j, n, m), n, m);

for (int k = 0; k < 4; ++k) {
int x = i + dx[k];
int y = j + dy[k];

if (valid(n, m, x, y)) {
set(b, x, y, 1 - get(b, x, y, n, m), n, m);
}
}

if (!used[b]) {
q.push(b);
dp[b] = dp[a] + 1;

if (b == zero) {
return dp[b];
}
}
}
}
}

return -1;
}
};
57 changes: 57 additions & 0 deletions C++/Recover-a-Tree-From-Preorder-Traversal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* 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* recoverFromPreorder(string s) {
int i = 0;
int n = s.size();

vector<pair<int, int>> vp;
while (i < n) {
int cnt = 0;
while (i < n && s[i] == '-') {
++cnt;
++i;
}

string num;
while (i < n && '0' <= s[i] && s[i] <= '9') {
num += s[i];
++i;
}

int m = stoi(num);

vp.push_back({cnt, m});
}

map<int, pair<int, TreeNode*>> last;

TreeNode * result = new TreeNode(vp[0].second);

last[vp[0].first] = {0, result};

for (int i = 1; i < vp.size(); ++i) {
if (last[vp[i].first - 1].first == 0) {
last[vp[i].first - 1].second->left = new TreeNode(vp[i].second);
last[vp[i].first - 1].first = 1;
last[vp[i].first] = {0, last[vp[i].first - 1].second->left};
} else {
last[vp[i].first - 1].second->right = new TreeNode(vp[i].second);
last[vp[i].first - 1].first = 2;
last[vp[i].first] = {0, last[vp[i].first - 1].second->right};
}
}

return result;
}
};
66 changes: 66 additions & 0 deletions C++/Unique-Paths-III.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// I am using here backtracking with memoization (look at 'used').
class Solution {
private:
int n;
int m;
int answer = 0;
int required = 0;

bool isValid(int x, int y) {
return (0 <= x && x < n) && (0 <= y && y < m);
}

void dfs(vector<vector<int>> &grid, pair<int, int> s, pair<int, int> e, vector<pair<int, int>>& st, vector<vector<bool>> &used) {
if (!st.empty() && st.back() == e && st.size() == required - 1) {
++answer;

return;
}

vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {-1, 0, 1, 0};

used[s.first][s.second] = true;
for (int i = 0; i < 4; ++i) {
if (isValid(s.first + dx[i], s.second + dy[i]) && (grid[s.first + dx[i]][s.second + dy[i]] == 0 || grid[s.first + dx[i]][s.second + dy[i]] == 2) && !used[s.first + dx[i]][s.second + dy[i]]) {
used[s.first + dx[i]][s.second + dy[i]] = true;
st.push_back({s.first + dx[i], s.second + dy[i]});
dfs(grid, {s.first + dx[i], s.second + dy[i]}, e, st, used);
st.pop_back();
used[s.first + dx[i]][s.second + dy[i]] = false;
}
}
}
public:
int uniquePathsIII(vector<vector<int>>& grid) {
n = (int) grid.size();
m = (int) grid[0].size();

pair<int, int> s;
pair<int, int> e;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (grid[i][j] == 1) {
s = {i, j};
++required;
}

if (grid[i][j] == 2) {
e = {i, j};
++required;
}

if (grid[i][j] == 0) {
++required;
}
}
}

vector<pair<int, int>> st;
vector<vector<bool>> used(n, vector<bool> (m, false));
used[s.first][s.second] = true;
dfs(grid, s, e, st, used);

return answer;
}
};
Loading