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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
#pragma once
#include "list_node.hpp"

class Solution {
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
ListNode *addTwoNumbers(const ListNode *l1, const ListNode *l2) {
ListNode fake, *p{&fake};
int carry = 0;
while (l1 != nullptr || l2 != nullptr || carry != 0) {
Expand Down
51 changes: 51 additions & 0 deletions leetcode/0002/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "solution.hpp"
#include "test_utility.hpp"

#include <ranges>

using namespace testing;
namespace {
using SolutionList = TypeList<Solution>;
struct TestCase {
TestCase(const YAML::Node &node) {
Decode(node["input"]["l1"], input.l1);
Decode(node["input"]["l2"], input.l2);
Decode(node["expected"], expected);
}
struct {
std::vector<int> l1;
std::vector<int> l2;
} input;
std::vector<int> expected;
};

template <typename Solution>
void RunTest(const std::vector<int> &l1, const std::vector<int> &l2, const std::vector<int> &expceted) {
// 检查约束条件
auto assertList = [](const std::vector<int> &l) {
// The number of nodes in each linked list is in the range [1, 100]
ASSERT_THAT(l.size(), AllOf(Ge(1), Le(100)));
ASSERT_THAT(l, Each(AllOf(Ge(0), Le(9)))); // 0 <= Node.val <= 9
// It is guaranteed that the list represents a number that does not have leading zeros
if (l.size() > 1) {
ASSERT_GT(l.back(), 0);
}
};
assertList(l1);
assertList(l2);

// 验证目标函数
Solution solution;
EXPECT_EQ(FromList(solution.addTwoNumbers(ToList(l1), ToList(l2))), expceted);
ListNode::Clear();
}

template <typename Solution>
void RunTest(const TestCase &tc) {
RunTest<Solution>(tc.input.l1, tc.input.l2, tc.expected);
}

TEST_Y(LeetCode2, Example1);
TEST_Y(LeetCode2, Example2);
TEST_Y(LeetCode2, Example3);
} // namespace
17 changes: 17 additions & 0 deletions leetcode/0002/test_suite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
example1:
input:
l1: [2,4,3]
l2: [5,6,4]
expected: [7,0,8]

example2:
input:
l1: [0]
l2: [0]
expected: [0]

example3:
input:
l1: [9,9,9,9,9,9,9]
l2: [9,9,9,9]
expected: [8,9,9,9,0,0,0,1]
1 change: 1 addition & 0 deletions leetcode/0002/title.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add-two-numbers
19 changes: 19 additions & 0 deletions leetcode/list_node.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "tracker.hpp"
#include <ranges>

struct ListNode : public Tracker<ListNode> {
int val;
Expand All @@ -8,3 +9,21 @@ struct ListNode : public Tracker<ListNode> {
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};

ListNode *ToList(const std::vector<int> &vec) {
ListNode *head{nullptr};
for (const auto &val : vec | std::views::reverse) {
ListNode *n{new ListNode(val, head)};
head = n;
}
return head;
}

std::vector<int> FromList(const ListNode *head) {
std::vector<int> vec;
while (head != nullptr) {
vec.push_back(head->val);
head = head->next;
}
return vec;
}
1 change: 1 addition & 0 deletions leetcode/test_utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ auto GetTestSuite(const std::string &testSuitePath) {
template <typename TestCase>
const TestCase &GetTestCase() {
static const auto path{GetTestSuitePath()};
// TODO(resserops): 每个TestSuite结束后清理
static const auto testSuite{GetTestSuite<TestCase>(path)};
assert(path == GetTestSuitePath());
return testSuite.at(GetTestCaseName());
Expand Down