my_leetcode/cpp/src/Solution.h

237 lines
7.6 KiB
C++

//
// Created by youyou on 2020/7/28.
//
#ifndef MY_LEETCODE_SOLUTION_H
#define MY_LEETCODE_SOLUTION_H
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <semaphore.h>
#include <queue>
#include <stack>
#include "structure.h"
using namespace std;
class Solution {
public:
/**
* 数组异或运算
* @param n
* @param start
* @return
*/
static int xorOperation(int n, int start);
/**
* 平方根
* @param x
* @return x的平方根 取整
*/
static int mySqrt(int x);
/**
* 141.环形链表
* @param head 链表
* @return 是否存在环
*/
static bool hasCycle(ListNode *head);
/**
* 740.删除并获得点数
* @param nums 整数数组
* @return 点数
*/
static int deleteAndEarn(vector<int> &nums) {
vector<int> s(*max_element(nums.begin(), nums.end()) + 1, 0);
for_each(nums.begin(), nums.end(), [&](int v) { s[v] += v; });
return accumulate(s.begin(), s.end(), pair<int, int>(0, 0), [](pair<int, int> a, int x) { return std::make_pair(a.second, max(a.first + x, a.second)); }).second;
}
/**
* 213.打家劫舍 II
* @param nums 整数数组
* @return 点数
*/
static int rob2(vector<int> &nums) {
auto func = [](pair<int, int> a, int x) { return std::make_pair(a.second, max(a.second, a.first + x)); };
return max(max(accumulate(nums.begin(), nums.end() - 1, pair<int, int>(0, 0), func).second,
accumulate(nums.begin() + 1, nums.end(), pair<int, int>(0, 0), func).second), nums[0]);
}
/**
* 237.删除链表中的节点
*
* @param node 节点
* @see <a href="https://leetcode-cn.com/problems/delete-node-in-a-linked-list/">原题链接</a>
*/
static void deleteNode(ListNode *node) {
ListNode *del = node->next;
node->val = node->next->val;
node->next = node->next->next;
delete del;
}
/**
* 268.丢失的数字
*
* @param nums 数组
* @return 丢失的数字
* @see <a href="https://leetcode-cn.com/problems/missing-number/">原题链接</a>
*/
static int missingNumber(vector<int> &nums) {
return std::vector<int>{(int) nums.size(), 1, (int) nums.size() + 1, 0}[nums.size() & 3] ^
std::accumulate(nums.begin(), nums.end(), 0, [](int o, int n) { return o ^ n; });
}
/**
* 101.对称二叉树
*
* @param root 二叉树
* @return 是否是对称二叉树
* @see <a href="https://leetcode-cn.com/problems/symmetric-tree/">原题链接</a>
*/
static bool isSymmetric(TreeNode *root) {
if (root) {
queue<TreeNode *> q;
q.push(root->left);
q.push(root->right);
while (!q.empty()) {
TreeNode *l = q.front();
q.pop();
TreeNode *r = q.front();
q.pop();
if (!l && !r) {
continue;
}
if (!l || !r || l->val != r->val) {
return false;
}
q.push(l->left);
q.push(r->right);
q.push(l->right);
q.push(r->left);
}
}
return true;
/*return !root || check(root->left, root->right);*/
/*return !root || [](TreeNode *l, TreeNode *r) {
const auto &s = [&](auto &&self, TreeNode *l, TreeNode *r) -> bool {
return (!l && !r) || (l && r) && (l->val == r->val) && self(self, l->left, r->right) && self(self, l->right, r->left);
};
return s(s, l, r);
}(root->left, root->right);*/
/*return !root || (!root->left && !root->right) || (root->left && root->right) && (root->left->val == root->right->val) &&
isSymmetric(new TreeNode(0, root->left->left, root->right->right)) &&
isSymmetric(new TreeNode(0, root->left->right, root->right->left));*/
}
static bool check(TreeNode *l, TreeNode *r) {
return (!l && !r) || (l && r) && (l->val == r->val) && check(l->left, r->right) && check(l->right, r->left);
}
bool isValid(const string& s) {
if (s.size() & 1) return false;
std::stack<char> stack;
for (char c: s)
if (c == '(' || c == '[' || c == '{') stack.push(c + (1 << (c & 1)));
else if (stack.empty() || stack.top() != c) return false;
else stack.pop();
return stack.empty();
}
/**
* 640. 求解方程
* @param equation 方程式
* @return 解
* @see <a href="https://leetcode-cn.com/problems/solve-the-equation/">原题链接</a>
*/
static string solveEquation(const string& equation) {
/*int a = 0, b = 0, c = 0, sign = 1, left = 1;
bool hasC = false;
for(char z : equation) {
switch (z) {
case 'x':
a += hasC ? sign * left * c : sign * left, c = 0, hasC = false;
break;
case '+':
b += sign * left * c, c = 0, sign = 1, hasC = false;
break;
case '-':
b += sign * left * c, c = 0, sign = -1, hasC = false;
break;
case '=':
b += sign * left * c, c = 0, sign = 1, left = -1, hasC = false;
break;
default:
c = c * 10 + z - '0', hasC = true;
break;
}
}
b += sign * left * c;
if (a == 0 && b == 0) {
return "Infinite solutions";
} else if (a == 0) {
return "No solution";
} else {
return "x=" + std::to_string(-b / a);
}*/
if (struct Status {
int a = 0, b = 0, c = 0, sign = 1, left = 1, hasC = false;
} s = std::accumulate(equation.begin(), equation.end(), Status{}, [](Status s, char z) {
switch (z) {
case 'x':
return Status{s.a + (s.hasC ? s.sign * s.left * s.c : s.sign * s.left), s.b, 0, s.sign, s.left, false};
case '+':
return Status{s.a, s.b + s.sign * s.left * s.c, 0, 1, s.left, false};
case '-':
return Status{s.a, s.b + s.sign * s.left * s.c, 0, -1, s.left, false};
case '=':
return Status{s.a, s.b + s.sign * s.left * s.c, 0, 1, -1, false};
default:
return Status{s.a, s.b, s.c * 10 + z - '0', s.sign, s.left, true};
}
}); s.a)
return "x=" + std::to_string(-(s.b + s.sign * s.left * s.c) / s.a);
else
return s.b + s.sign * s.left * s.c ? "No solution" : "Infinite solutions";
}
};
/**
* 1114.按序打印
*
* @see <a href="https://leetcode-cn.com/problems/print-in-order/">原题链接</a>
*/
class Foo {
protected:
sem_t firstJobDone{};
sem_t secondJobDone{};
public:
Foo() {
sem_init(&firstJobDone, 0, 0);
sem_init(&secondJobDone, 0, 0);
}
void first(const function<void()> &printFirst) {
printFirst();
sem_post(&firstJobDone);
}
void second(const function<void()> &printSecond) {
sem_wait(&firstJobDone);
printSecond();
sem_post(&secondJobDone);
}
void third(const function<void()> &printThird) {
sem_wait(&secondJobDone);
printThird();
}
};
#endif //MY_LEETCODE_SOLUTION_H