Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added LeetCode problem 1,2 #2450

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/leetcode_directory_writer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# The objective of this GitHub Action is to update the leetcode DIRECTORY.md file (if needed)
# when doing a git push
name: leetcode_directory_writer
on:
push:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this for every push? 🤔 I think it suffices to have this for a pull_request instead... What do you think @Panquesito7?

paths:
- 'leetcode/src/**.cpp'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-python@v4
with:
python-version: 3.x
- name: Add python dependencies
run: |
pip install requests
- name: Commit and push changes
uses: stefanzweifel/git-auto-commit-action@v4
id: commit-push
with:
commit_message: 'docs: updating `leetcode/DIRECTORY.md`'
branch: 'leetcode-directory-${{ github.sha }}'
create_branch: true
69 changes: 69 additions & 0 deletions leetcode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 📚 Contributing 📚

We're glad you're interested in adding C++ LeetCode solutions to the repository.\
Here we'll be explaining how to contribute to LeetCode solutions properly.

## 💻 Cloning/setting up the project 💻

First off, you'll need to fork the repository [**here**](https://github.com/TheAlgorithms/C-Plus-Plus/fork).\
Then, you'll need to clone the repository to your local machine.

```bash
git clone https://github.com/your-username/C-Plus-Plus.git
```

After that, you'll need to create a new branch for your solution.

```bash
git checkout -b solution/your-solution-name
```

## 📝 Adding a new solution 📝

All LeetCode problems can be found [**here**](https://leetcode.com/problemset/all/).\
If you have a solution to any of these problems (which are not being **repeated**, that's great! Here are the steps:

1. Add a new file in `leetcode/src` with the number of the problem.
- For example: if the problem's number is 98, the filename should be `98.cpp`.
2. Provide a small description of the solution at the top of the file. A function should go below that. For example:

```c
/**
* Return an vector of vector of size returnSize.
* The sizes of the vectors are returned as returnColumnSizes vector.
* Note: Both returned vector and columnSizes vector must be dynamically allocated, assume caller calls free.
*/
```

3. Do not provide a `main` function. Use the required standalone functions instead.
4. Doxygen documentation isn't used in LeetCode solutions. Simple/small documentation or comments should be fine.
5. Please include dependency libraries/headers such as `<iostream>`, `<vector>` along with the `Solution` class to the problem. This will help the CI to succeed without the dependency errors.

> **Note**
> There was a requirement to update the `leetcode/DIRECTORY.md` file with details of the solved problem. It's not required anymore. The information about the problem is fetched automatically throughout the LeetCode API.

## 📦 Committing your changes 📦

Once you're done with adding a new LeetCode solution, it's time we make a pull request.

1. First, stage your changes.

```bash
git add leetcode/src/98.cpp # Use `git add .` to stage all changes.
```

2. Then, commit your changes.

```bash
git commit -m "feat: add LeetCode problem 98" -m "Commit description" # Optional
```

3. Finally, push your changes to your forked repository.

```bash
git push origin solution/your-solution-name:solution/your-solution-name
```

4. You're done now! You just have to make a [**pull request**](https://github.com/TheAlgorithms/C-Plus-Plus/compare). 🎉

If you need any help, don't hesitate to ask and join our [**Discord server**](https://the-algorithms.com/discord)! 🙂
27 changes: 27 additions & 0 deletions leetcode/src/1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Given an array of integers nums and an integer target, return indices of the
* two numbers such that they add up to target.
* You may assume that each input would have exactly one solution, and you may not use the same element twice.
*/

#include <vector>
#include <unordered_map>
class Solution {
public:
std::vector<int> twoSum(std::vector<int>& nums, int target) {
std::unordered_map<int, int> mp; // value:index
std::vector<int> res;

for (int i = 0; i < nums.size(); i++) {
int diff = target - nums[i];

if (mp.find(diff) != mp.end()) {
res.push_back(mp[diff]);
res.push_back(i);
return res;
}
mp[nums[i]] = i;
}
return res;
}
};
40 changes: 40 additions & 0 deletions leetcode/src/2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* You are given two non - empty linked lists representing two non - negative integers.
* The digits are stored in reverse order, and each of their nodes contains a single digit.
* Add the two numbersand return the sum as a linked list.
*/

#include <memory>

/*
* Definition for singly-linked list.
*/
struct ListNode {
int val;
ListNode *next;
explicit ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry = 0;
std::unique_ptr<ListNode> head(new ListNode(0));
ListNode* sum = head.get();

while(l1 || l2) {
int val = carry + (l1 ? l1->val : 0) + (l2 ? l2->val : 0);
carry = val/10;
sum->next = new ListNode(val%10);
sum = sum->next;
l1 = (l1 ? l1->next : nullptr);
l2 = (l2 ? l2->next : nullptr);
}
if(carry){
sum->next = new ListNode(carry);
}

return head->next;
}
};
124 changes: 124 additions & 0 deletions scripts/leetcode_directory_md.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/env python3

from dataclasses import dataclass
from os import listdir
from pathlib import Path

import requests


@dataclass
class Task:
"""The task dataclass. Container for task info"""

id: str
title: str
solution: str
difficulty: str


def fetch_leetcode_folder_tasks(solutions_folder: Path) -> list[Task]:
"""Fetch leetcode tasks from the Leetcode"""

# Fetch tasks info from the leetcode API.
resp = requests.get("https://leetcode.com/api/problems/algorithms/", timeout=10)
content_dict = resp.json()

raw_tasks_id_dict = {}

for task in content_dict["stat_status_pairs"]:
task_stat = task["stat"]
raw_tasks_id_dict[str(task_stat["frontend_question_id"])] = task

# Generate result tasks info to be inserted into the document
tasks_list = []

difficulty = {1: "Easy", 2: "Medium", 3: "Hard"}

for fl in listdir(solutions_folder):
task_id = fl.split(".")[0]

raw_task = raw_tasks_id_dict.get(task_id, None)
if raw_task is None:
continue

raw_task_stat = raw_task["stat"]
tasks_list.append(
Task(
id=f'{raw_task_stat["frontend_question_id"]}',
title=f'[{raw_task_stat["question__title"]}](https://leetcode.com/problems/{raw_task_stat["question__title_slug"]})',
solution=f"[C++](./src/{fl})",
difficulty=f'{difficulty.get(raw_task["difficulty"]["level"], "")}',
)
)

return tasks_list


HEADER_ID = "#"
HEADER_TITLE = "Title"
HEADER_SOLUTION = "Solution"
HEADER_DIFFICULTY = "Difficulty"
SEPARATOR = "-"


def print_directory_md(tasks_list: list[Task]) -> None:
"""Print tasks into the stdout"""

def get_max_len(get_item):
return max(list(map(lambda x: len(get_item(x)), tasks_list)))

id_max_length = max(get_max_len(lambda x: x.id), len(HEADER_ID))
title_max_length = max(get_max_len(lambda x: x.title), len(HEADER_TITLE))
solution_max_length = max(get_max_len(lambda x: x.solution), len(HEADER_SOLUTION))
difficulty_max_length = max(
get_max_len(lambda x: x.difficulty), len(HEADER_DIFFICULTY)
)

def formatted_string(header, title, solution, difficulty):
return (
f"| {header.rjust(id_max_length)} "
+ f"| {title.ljust(title_max_length)} "
+ f"| {solution.ljust(solution_max_length)} "
+ f"| {difficulty.ljust(difficulty_max_length)} |"
)

tasks_rows = []

tasks_rows.append(
formatted_string(HEADER_ID, HEADER_TITLE, HEADER_SOLUTION, HEADER_DIFFICULTY)
)
tasks_rows.append(
formatted_string(
id_max_length * SEPARATOR,
title_max_length * SEPARATOR,
solution_max_length * SEPARATOR,
difficulty_max_length * SEPARATOR,
)
)

tasks_list.sort(key=lambda x: int(x.id.strip()))

for task in tasks_list:
tasks_rows.append(
formatted_string(task.id, task.title, task.solution, task.difficulty)
)

print(
"""
# LeetCode

### LeetCode Algorithm
"""
)

for item in tasks_rows:
print(item)


if __name__ == "__main__":
top_dir = Path(".")
solutions_folder = top_dir / "leetcode" / "src"

tasks_list = fetch_leetcode_folder_tasks(solutions_folder)
print_directory_md(tasks_list)