Skip to content

Commit

Permalink
Merge branch 'leetcode'
Browse files Browse the repository at this point in the history
  • Loading branch information
iglesias committed May 6, 2024
2 parents f3bb70a + 82dea7c commit 38bb3d9
Show file tree
Hide file tree
Showing 6 changed files with 301 additions and 67 deletions.
50 changes: 18 additions & 32 deletions leetcode/404.cpp
Original file line number Diff line number Diff line change
@@ -1,48 +1,34 @@
#include <memory>
#include <vector>
#include <stdexcept>

#include <gtest/gtest.h>

struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
#include "tree.h"

int sumOfLeftLeaves(TreeNode *root) {
if (!root or (!root->left and !root->right))
return 0;
int sumOfLeftLeaves(TreeNode *root)
{
if (!root or (!root->left and !root->right)) return 0;
int ans = 0;
if (root->left) {
if (!root->left->left and !root->left->right) {
if (!root->left->left and !root->left->right)
ans += root->left->val;
} else {
ans += sumOfLeftLeaves(root->left);
}
}
else
ans += sumOfLeftLeaves(root->left); }
return ans + sumOfLeftLeaves(root->right);
}

TEST(sumOfLeftLeaves, SampleInput) {
auto root{std::make_unique<TreeNode>(3)};

// FIXME const construction.
std::vector<std::unique_ptr<TreeNode>> otherNodes;
otherNodes.push_back(std::make_unique<TreeNode>(9));
otherNodes.push_back(std::make_unique<TreeNode>(20));
otherNodes.push_back(std::make_unique<TreeNode>(15));
otherNodes.push_back(std::make_unique<TreeNode>(7));

root->left = otherNodes[0].get();
root->right = otherNodes[1].get();
root->right->left = otherNodes[2].get();
root->right->right = otherNodes[3].get();

TEST(sumOfLeftLeaves, SampleInput)
{
const auto& [root, _] = make_tree({3, 9, 20, 15, 7});
EXPECT_EQ(sumOfLeftLeaves(root.get()), 24);
}

int main(int argc, char **argv) {
TEST(make_tree, EmptyVector)
{
EXPECT_THROW(static_cast<void>(make_tree({})), std::out_of_range);
}

int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
121 changes: 121 additions & 0 deletions leetcode/514.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include <queue>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "gtest/gtest.h"

using namespace std;

struct state {
int c;
int i;
int n;
state() : c(0), i(0), n(0) {}
bool operator>(state const& other) const {
if (c == other.c)
return n > other.n;
else
return c > other.c;
}
};

int l;

using lookup_t = vector<unordered_map<char, vector<pair<int, bool>>>>;

lookup_t preprocess(string_view ring) {
lookup_t lookup = vector(l, unordered_map<char, vector<pair<int, bool>>>());
for (int i = 0; i < l; i++) {
// +1
int j = (i + 1) % l;
int n = 1;
while (j != i) {
lookup[i][ring[j]].emplace_back(n, true);
n++;
j = (j + 1) % l;
}
// -1
j = i - 1; if (j < 0) j += l;
n = 1;
while (j != i) {
lookup[i][ring[j]].emplace_back(n, false);
n++;
j--; if (j < 0) j += l;
}
}
return lookup;
}

struct pair_hash {
template <class T1, class T2>
std::size_t operator () (const std::pair<T1,T2> &p) const {
auto h1 = std::hash<T1>{}(p.first);
auto h2 = std::hash<T2>{}(p.second);
return h1 ^ h2;
}
};

int findRotateSteps(string ring, string key) {
l = static_cast<int>(ring.length());
auto lookup = preprocess(ring);

priority_queue<state, vector<state>, greater<state>> PQ;
unordered_map<pair<int, int>, int, pair_hash> PQed;
auto updateQs = [&](const state& s){
if (PQed.contains(make_pair(s.c, s.i))) {
if (PQed[make_pair(s.c, s.i)] > s.n) {
PQ.emplace(s);
PQed[make_pair(s.c, s.i)] = s.n;
}
} else {
PQ.emplace(s);
PQed.emplace(make_pair(s.c, s.i), s.n);
}
};
updateQs(state{});

while (!PQ.empty()) {
state s{PQ.top()}; // FIXME: with queue::front -> state&
if (s.c == static_cast<int>(key.length())) {
return s.n;
} else if (key[s.c] == ring[s.i]) {
s.n++;
s.c++;
updateQs(s);
} else {
const int n0 = s.n;
const int i0 = s.i;
for (const auto& item : lookup[i0][key[s.c]]) {
s.n = n0 + item.first;
if (item.second)
s.i = (i0 + item.first) % l;
else {
s.i = i0 - item.first;
if (s.i < 0) s.i += l;
}
updateQs(s);
}
}
PQ.pop();
}
return -1;
}

TEST(FreedomTrail, case1) {
ASSERT_EQ(findRotateSteps("godding", "gd"), 4);
}

TEST(FreedomTrail, case2) {
ASSERT_EQ(findRotateSteps("godding", "godding"), 13);
}

TEST(FreedomTrail, testcase299) {
ASSERT_EQ(findRotateSteps("erzjaclvkmqssenbrxmsyisgudxkurxgoxxqgxekexrcdcmggbgetiqhnhkabhdjsopkykdtsccvcylqoyjqotgrqtkibggulwlh", "hyoosmcpkliigxrkgrgxrymcsenbkdheqxamtkzbusekckicxtqhuwbcjaxsynhlrxxlrqutsdylgddteovvgsgocgqejqbgkgqj"), 832);
}

int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
56 changes: 56 additions & 0 deletions leetcode/834.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <vector>

#include <gtest/gtest.h>

using namespace std;

namespace {

vector<vector<int>> A; // adjacency list
vector<int> sizes, ans; // sub-trees' sizes (#nodes inc. root), sum of distances

void init(const int n, const vector<vector<int>>& edges) {
A = vector(n, vector<int>());
for (const vector<int>& edge: edges) {
A[edge[0]].push_back(edge[1]);
A[edge[1]].push_back(edge[0]);
}
sizes.assign(n, 1);
ans.resize(n);
}

void DFS(const int i = 0, const int parent = -1) {
for (const int j : A[i]) {
if (j == parent) continue;
DFS(j, i);
sizes[i] += sizes[j];
ans[i] += ans[j] + sizes[j];
}
}

void reRoot(const int i = 0, const int parent = -1) {
for (const int j : A[i]) {
if (j == parent) continue;
ans[j] = ans[i] + static_cast<int>(A.size()) - 2 * sizes[j];
reRoot(j, i);
}
}

} // namespace

vector<int> sumOfDistancesInTree(int n, const vector<vector<int>>& edges) {
::init(n, edges);
::DFS();
::reRoot();
return ::ans;
}

TEST(sumOfDistancesInTree, Sample) {
const vector<vector<int>> edges = {{0, 1}, {0, 2}, {2, 3}, {2, 4}, {2, 5}};
EXPECT_EQ(sumOfDistancesInTree(6, edges), vector<int>({8, 12, 6, 10, 10, 10}));
}

int main(int argc, char *argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
37 changes: 37 additions & 0 deletions leetcode/tree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <memory>
#include <utility>
#include <vector>

using std::pair;
using std::make_unique;
using std::unique_ptr;
using std::vector;

struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

pair<unique_ptr<TreeNode>, vector<unique_ptr<TreeNode>>>
make_tree(const vector<int>& v) {
auto root{std::make_unique<TreeNode>(v.at(0))};

// FIXME const construction.
vector<unique_ptr<TreeNode>> otherNodes;
//TODO use actual data in v to construct the tree.
otherNodes.push_back(make_unique<TreeNode>(9));
otherNodes.push_back(make_unique<TreeNode>(20));
otherNodes.push_back(make_unique<TreeNode>(15));
otherNodes.push_back(make_unique<TreeNode>(7));

root->left = otherNodes[0].get();
root->right = otherNodes[1].get();
root->right->left = otherNodes[2].get();
root->right->right = otherNodes[3].get();

return std::make_pair(std::move(root), std::move(otherNodes));
}
Loading

0 comments on commit 38bb3d9

Please sign in to comment.