add: 220505 [cpp]
This commit is contained in:
parent
c9c4474306
commit
831d74a79f
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -3,4 +3,4 @@ PROJECT(2205)
|
|||
|
||||
SET(CMAKE_CXX_STANDARD 23)
|
||||
|
||||
ADD_EXECUTABLE(2204 220505.cpp)
|
||||
ADD_EXECUTABLE(2205 220506.cpp)
|
||||
|
|
|
|||
Loading…
Reference in New Issue