Skip to content

Commit d200d74

Browse files
authored
Uploaded solutions for bunch of hard problems (#30)
* Uploaded solutions for bunch of hard problems in C++ * Updated README.md * Changed difficulty of LRU Cache problem
1 parent c39d712 commit d200d74

6 files changed

+379
-0
lines changed

C++/Cherry-Pickup-II.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Solution {
2+
private:
3+
// Let's run a simple dfs. If we come to the same cell with two robots, let's subtract that value.
4+
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) {
5+
if (c1 < 0 || c1 >= m || c2 < 0 || c2 >= m) {
6+
return 0;
7+
} else if (r == n) {
8+
return 0;
9+
} else if (dp.count({r, {c1, c2}}) > 0) {
10+
return dp[{r, {c1, c2}}];
11+
} else {
12+
int current_ceil = grid[r][c1] + grid[r][c2];
13+
14+
// Here is that subtraction
15+
if (c1 == c2) {
16+
current_ceil -= grid[r][c2];
17+
}
18+
19+
// Running dfs from all possible cells
20+
int mx = 0;
21+
for (int i = -1; i <= 1; ++i) {
22+
for (int j = -1; j <= 1; ++j) {
23+
mx = max(mx, dfs(n, m, r + 1, c1 + i, c2 + j, dp, grid));
24+
}
25+
}
26+
27+
return dp[{r, {c1, c2}}] = current_ceil + mx;
28+
}
29+
}
30+
public:
31+
int cherryPickup(vector<vector<int>>& grid) {
32+
unordered_map<pair<int, pair<int, int>>, int> dp;
33+
34+
int n = grid.size();
35+
int m = grid[0].size();
36+
37+
return dfs(n, m, 0, 0, m - 1, dp, grid);
38+
}
39+
};

C++/LRU-Cache.cpp

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Here I am using a hashmap to store a node pointer by a key. It will give us O(1) for all operations.
2+
class LRUCache {
3+
private:
4+
struct Node {
5+
Node *left = nullptr;
6+
Node *right = nullptr;
7+
8+
int key;
9+
int value;
10+
11+
Node(int key, int value) : key(key), value(value) {}
12+
};
13+
14+
Node *root = nullptr;
15+
16+
Node *tail = nullptr;
17+
18+
unordered_map<int, Node*> hashmap;
19+
20+
int capacity;
21+
22+
void update_root(Node *node) {
23+
Node *tmp = root;
24+
if (tail == nullptr) {
25+
tail = node;
26+
} else if (tail == node) {
27+
tail = node;
28+
29+
if (node->left != nullptr) {
30+
tail = node->left;
31+
}
32+
}
33+
34+
if (root == nullptr) {
35+
root = node;
36+
tmp = root;
37+
return;
38+
}
39+
40+
if (root != node) {
41+
Node *t = node->left;
42+
if (t != nullptr) {
43+
t->right = node->right;
44+
if (node->right != nullptr) {
45+
node->right->left = t;
46+
}
47+
}
48+
49+
node->right = root;
50+
root->left = node;
51+
root = node;
52+
}
53+
}
54+
55+
public:
56+
LRUCache(int capacity) : capacity(capacity) {}
57+
58+
int get(int key) {
59+
if (hashmap.count(key) == 0) {
60+
return -1;
61+
} else {
62+
Node *node = hashmap[key];
63+
64+
update_root(node);
65+
66+
return root->value;
67+
}
68+
}
69+
70+
void put(int key, int value) {
71+
if ((int) hashmap.size() == capacity && hashmap.count(key) == 0) {
72+
hashmap.erase(tail->key);
73+
Node *new_tail = nullptr;
74+
if (tail->left != nullptr) {
75+
new_tail = tail->left;
76+
}
77+
tail->left = nullptr;
78+
tail = nullptr;
79+
80+
tail = new_tail;
81+
if (tail != nullptr) {
82+
tail->right = nullptr;
83+
}
84+
}
85+
86+
Node *node;
87+
if (hashmap.count(key) == 0) {
88+
node = new Node(key, value);
89+
} else {
90+
node = hashmap[key];
91+
}
92+
node->value = value;
93+
94+
hashmap[key] = node;
95+
update_root(node);
96+
}
97+
};
98+
99+
/**
100+
* Your LRUCache object will be instantiated and called as such:
101+
* LRUCache* obj = new LRUCache(capacity);
102+
* int param_1 = obj->get(key);
103+
* obj->put(key,value);
104+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// The main algorithm in this problem is Breadth First Search.
2+
class Solution {
3+
private:
4+
bool valid(int n, int m, int x, int y) {
5+
return (0 <= x && x < n) && (0 <= y && y < m);
6+
}
7+
8+
string convert(vector<vector<int>> &c, int n, int m) {
9+
string s;
10+
11+
for (int i = 0; i < n; ++i) {
12+
for (int j = 0; j < m; ++j) {
13+
s += c[i][j] + '0';
14+
}
15+
}
16+
17+
return s;
18+
}
19+
20+
int get(string s, int i, int j, int n, int m) {
21+
return s[i * m + j] - '0';
22+
}
23+
24+
void set(string &s, int i, int j, int val, int n, int m) {
25+
s[i * m + j] = val + '0';
26+
}
27+
28+
public:
29+
int minFlips(vector<vector<int>>& c) {
30+
int n = c.size();
31+
int m = c[0].size();
32+
33+
map<string, int> dp;
34+
map<string, bool> used;
35+
36+
vector<int> dx = {-1, 0, 1, 0};
37+
vector<int> dy = {0, 1, 0, -1};
38+
39+
string cToNum = convert(c, n, m);
40+
string zero(n * m, '0');
41+
42+
if (cToNum == zero) {
43+
return 0;
44+
}
45+
46+
queue<string> q;
47+
q.push(cToNum);
48+
49+
dp[cToNum] = 0;
50+
51+
while (!q.empty()) {
52+
string a = q.front();
53+
q.pop();
54+
55+
used[a] = true;
56+
57+
for (int i = 0; i < n; ++i) {
58+
for (int j = 0; j < m; ++j) {
59+
string b = a;
60+
61+
set(b, i, j, 1 - get(b, i, j, n, m), n, m);
62+
63+
for (int k = 0; k < 4; ++k) {
64+
int x = i + dx[k];
65+
int y = j + dy[k];
66+
67+
if (valid(n, m, x, y)) {
68+
set(b, x, y, 1 - get(b, x, y, n, m), n, m);
69+
}
70+
}
71+
72+
if (!used[b]) {
73+
q.push(b);
74+
dp[b] = dp[a] + 1;
75+
76+
if (b == zero) {
77+
return dp[b];
78+
}
79+
}
80+
}
81+
}
82+
}
83+
84+
return -1;
85+
}
86+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* struct TreeNode {
4+
* int val;
5+
* TreeNode *left;
6+
* TreeNode *right;
7+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
8+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
9+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10+
* };
11+
*/
12+
class Solution {
13+
public:
14+
TreeNode* recoverFromPreorder(string s) {
15+
int i = 0;
16+
int n = s.size();
17+
18+
vector<pair<int, int>> vp;
19+
while (i < n) {
20+
int cnt = 0;
21+
while (i < n && s[i] == '-') {
22+
++cnt;
23+
++i;
24+
}
25+
26+
string num;
27+
while (i < n && '0' <= s[i] && s[i] <= '9') {
28+
num += s[i];
29+
++i;
30+
}
31+
32+
int m = stoi(num);
33+
34+
vp.push_back({cnt, m});
35+
}
36+
37+
map<int, pair<int, TreeNode*>> last;
38+
39+
TreeNode * result = new TreeNode(vp[0].second);
40+
41+
last[vp[0].first] = {0, result};
42+
43+
for (int i = 1; i < vp.size(); ++i) {
44+
if (last[vp[i].first - 1].first == 0) {
45+
last[vp[i].first - 1].second->left = new TreeNode(vp[i].second);
46+
last[vp[i].first - 1].first = 1;
47+
last[vp[i].first] = {0, last[vp[i].first - 1].second->left};
48+
} else {
49+
last[vp[i].first - 1].second->right = new TreeNode(vp[i].second);
50+
last[vp[i].first - 1].first = 2;
51+
last[vp[i].first] = {0, last[vp[i].first - 1].second->right};
52+
}
53+
}
54+
55+
return result;
56+
}
57+
};

C++/Unique-Paths-III.cpp

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// I am using here backtracking with memoization (look at 'used').
2+
class Solution {
3+
private:
4+
int n;
5+
int m;
6+
int answer = 0;
7+
int required = 0;
8+
9+
bool isValid(int x, int y) {
10+
return (0 <= x && x < n) && (0 <= y && y < m);
11+
}
12+
13+
void dfs(vector<vector<int>> &grid, pair<int, int> s, pair<int, int> e, vector<pair<int, int>>& st, vector<vector<bool>> &used) {
14+
if (!st.empty() && st.back() == e && st.size() == required - 1) {
15+
++answer;
16+
17+
return;
18+
}
19+
20+
vector<int> dx = {0, 1, 0, -1};
21+
vector<int> dy = {-1, 0, 1, 0};
22+
23+
used[s.first][s.second] = true;
24+
for (int i = 0; i < 4; ++i) {
25+
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]]) {
26+
used[s.first + dx[i]][s.second + dy[i]] = true;
27+
st.push_back({s.first + dx[i], s.second + dy[i]});
28+
dfs(grid, {s.first + dx[i], s.second + dy[i]}, e, st, used);
29+
st.pop_back();
30+
used[s.first + dx[i]][s.second + dy[i]] = false;
31+
}
32+
}
33+
}
34+
public:
35+
int uniquePathsIII(vector<vector<int>>& grid) {
36+
n = (int) grid.size();
37+
m = (int) grid[0].size();
38+
39+
pair<int, int> s;
40+
pair<int, int> e;
41+
for (int i = 0; i < n; ++i) {
42+
for (int j = 0; j < m; ++j) {
43+
if (grid[i][j] == 1) {
44+
s = {i, j};
45+
++required;
46+
}
47+
48+
if (grid[i][j] == 2) {
49+
e = {i, j};
50+
++required;
51+
}
52+
53+
if (grid[i][j] == 0) {
54+
++required;
55+
}
56+
}
57+
}
58+
59+
vector<pair<int, int>> st;
60+
vector<vector<bool>> used(n, vector<bool> (m, false));
61+
used[s.first][s.second] = true;
62+
dfs(grid, s, e, st, used);
63+
64+
return answer;
65+
}
66+
};

0 commit comments

Comments
 (0)