add: 220505 [cpp]

This commit is contained in:
eat-swap 2022-05-06 15:13:46 +08:00
parent c9c4474306
commit 831d74a79f
Signed by: Eatswap
GPG Key ID: BE661106A1F3FA0B
2 changed files with 150 additions and 1 deletions

149
cpp/2205/220506.cpp Normal file
View File

@ -0,0 +1,149 @@
#include <string>
#include <vector>
#include <chrono>
#include <iostream>
template<typename T>
struct ListNode {
T data;
ListNode<T>* prev;
ListNode<T>* next;
explicit ListNode(T d, ListNode<T>* p = nullptr, ListNode<T>* n = nullptr) : data(std::move(d)), prev(p), next(n) {}
ListNode(ListNode<T>* p, ListNode<T>* n) : prev(p), next(n) {}
};
template<typename T>
struct LinkedList {
unsigned long long size = 0;
ListNode<T>* front = nullptr;
ListNode<T>* rear = nullptr;
LinkedList() {
front = new ListNode((ListNode<T>*)nullptr, (ListNode<T>*)nullptr);
rear = new ListNode(front, (ListNode<T>*) nullptr);
front->next = rear;
}
void push_back(T data) {
auto* node = new ListNode(data, rear->prev, rear);
rear->prev = rear->prev->next = node;
++size;
}
ListNode<T>* erase(ListNode<T>* node) {
auto ret = node->next;
node->prev->next = node->next;
node->next->prev = node->prev;
delete node;
--size;
return ret;
}
bool empty() const {
return !size;
}
ListNode<T>* begin() {
return front->next;
}
ListNode<T>* end() {
return rear;
}
};
/**
* 1209. Remove All Adjacent Duplicates in String II
* You are given a string s and an integer k, a k duplicate removal consists of choosing k adjacent and equal letters from s and removing them, causing the left and the right side of the deleted substring to concatenate together.
* We repeatedly make k duplicate removals on s until we no longer can.
* Return the final string after all such duplicate removals have been made. It is guaranteed that the answer is unique.
*/
class Solution {
public:
static std::string removeDuplicates(const std::string& s, int k) {
if (s.empty())
return {};
LinkedList<std::pair<char, int>> cnt;
{
int c = 1;
char current = *s.c_str();
for (const char* ptr = s.c_str() + 1; *ptr; ++ptr) {
if (*ptr == current) {
++c;
continue;
}
cnt.push_back({current, c});
c = 1;
current = *ptr;
}
cnt.push_back({current, c});
}
// Remove & Merge
for (auto ptr = cnt.begin(); ptr != cnt.end();) {
// Now, nothing can be merged.
// Eliminate at once
ptr->data.second %= k;
// Check if totally removed
if (ptr->data.second) {
ptr = ptr->next;
continue;
}
// Totally removed!
// possible to be merged
ptr = cnt.erase(ptr);
if (cnt.empty())
break;
if (ptr != cnt.begin())
ptr = ptr->prev;
auto prevPtr = ptr;
ptr = ptr->next;
while (ptr != cnt.end() && prevPtr->data.first == ptr->data.first) {
prevPtr->data.second += ptr->data.second;
ptr = cnt.erase(ptr);
}
ptr = prevPtr;
}
std::string ret;
for (auto* ptr = cnt.begin(); ptr != cnt.end(); ptr = ptr->next) {
const auto [ch, n] = ptr->data;
ret.append(n, ch);
}
return ret;
}
};
class Stopwatch {
private:
std::chrono::high_resolution_clock::time_point start;
public:
Stopwatch() {
this->start = std::chrono::high_resolution_clock::now();
}
~Stopwatch() {
std::printf("Time elapsed: %.6lf ms\n", std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start).count() / 1000000.0);
}
};
int main() {
std::string arg;
arg.reserve(100000);
for (int i = 0; i < 1923; ++i)
arg += "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 1923; ++i)
arg += "zyxwvutsrqponmlkjihgfedcba";
{
Stopwatch s;
std::cout << Solution::removeDuplicates(arg, 2) << "\n";
}
return 0;
}

View File

@ -3,4 +3,4 @@ PROJECT(2205)
SET(CMAKE_CXX_STANDARD 23)
ADD_EXECUTABLE(2204 220505.cpp)
ADD_EXECUTABLE(2205 220506.cpp)