博弈-翻转|hash<string>|smid

lc267

回文排列

统计字符频率,确保++最多一个奇频字符(放回文中间)++

剩余字符成对用DFS回溯拼接左右,生成所有回文字符串,提前终止超长路径提速

class Solution {

public:

unordered_map<char, int> m;

vector<string> ans;

void dfs(string s, int n) {

if(s.size()>n)return;

if(s.size()==n){ans.push_back(s);return;}

for(++auto& [c,f]:m)if(f>0){++

f-=2;

++dfs(c+s+c,n)++ ;

f+=2;

}

}

vector<string> generatePalindromes(string s) {

int n=s.size(),o=0;

char oc;

for(char c:s)m[c]++;

for(auto& [c,f]:m)

if(f%2){

o++;oc=c;

if(o>1)return {};

}

string mid;

if(o)mid=oc,m[oc]--;

dfs(mid,n); //扩散法

return ans;

}

};

lc311

稀疏矩阵

预处理标记非0+二分

class Solution {

public:

vector<vector<int>> multiply(vector<vector<int>>& A, vector<vector<int>>& B) {

if (A.size() < 1 || B.size() < 1 || B[0].size() < 1) return {};

int m = A.size();

int n = A[0].size();

int k = B[0].size();

vector<vector<int>> a(m);

vector<vector<int>> b(k);

for (int i = 0; i < m; ++i) {

for (int j = 0; j < n; ++j) {

if (A[i][j] != 0) a[i].push_back(j);

}

}

for (int i = 0; i < n; ++i) {

for (int j = 0; j < k; ++j) {

if (B[i][j] != 0) b[j].push_back(i);

}

}

vector<vector<int>> res(m, vector<int>(k, 0));

for (int i = 0; i < m; ++i) {

for (int j = 0; j < k; ++j) {

if (a[i].size() < 1 || b[j].size() < 1) continue;

auto ai = a[i].begin();

auto bi = b[j].begin();

//int cur_max = 0;

int sum = 0;

while (ai != a[i].end() && bi != b[j].end()) {

//cur_max = max(*ai, *bi);

if (*ai == *bi) {

sum += A[i][*ai] * B[*bi][j];

ai++;

bi++;

}

else {

if (*ai > *bi) bi = lower_bound(bi, b[j].end(), *ai);

else ai = lower_bound(ai, a[i].end(), *bi);

}

}

res[i][j] = sum;

}

}

return res;

}

};

暴力

++//行列 对应位置 的乘积 和++

++res[r][c] += (mat1[r][j] * mat2[j][c]);++

class Solution

{

public:

vector<vector<int>> multiply(vector<vector<int>>& mat1, vector<vector<int>>& mat2)

{

int r1 = mat1.size(), r2 = mat2.size();

if (r1 == 0 || r2 == 0)

return vector<vector<int>>{};

int c1 = mat1[0].size(), c2 = mat2[0].size();

vector<vector<int>> res(r1, vector<int>(c2, 0));

for (int r = 0; r < r1; r ++)

{

for (int c = 0; c < c2; c ++)

{

for (int j = 0; j < c1; j ++) ++//行列 对应位置 的乘积 和++

{

++res[r][c] += (mat1[r][j] * mat2[j][c]);++

}

}

}

return res;

}

};

simd写法

行列遍历+跳过零元素+并行transform

逐元素累加实现矩阵乘法,计算ans[i][j] = mat1[i][l]*mat2[l][j]总和。

#include <execution>

class Solution {

public:

vector<vector<int>> multiply(vector<vector<int>>& mat1, vector<vector<int>>& mat2) {

int n = mat1.size(), k = mat2.size(), m = mat2[0].size();

vector ans(n, vector(m, 0));

for (int i = 0; i < n; ++i) {

for (int l = 0; l < k; ++l) {

int val = mat1[i][l];

if (!val) continue;

transform(execution::unseq, mat2[l].begin(), mat2[l].end(), ans[i].begin(), ans[i].begin(), [val](auto&& a, auto&& b) { ++return b + val * a;++ });

// ranges::transform(mat2[l], ans[i], ans[i].begin(), [val](auto&& a, auto&& b) { return b + val * a; });

}

}

return ans;

}

};

lc294

博弈论 memo 翻转

hash包装器

++size_t h = hash<string>()(cur);++

笔记一下没找到,大概就是注意无冲突的情况下,可以使用hash<string>()包装string

class Solution {

unordered_map<size_t, bool> memo;

public:

bool canWin(string &cur) {

++size_t h = hash<string>()(cur);++

if (memo.count(h))

return memo[h];

for (int i = 1; i < cur.size(); i++)

{

if (cur[i] == '+' && cur[i - 1] == '+')

{

cur[i] = cur[i - 1] = '-';

bool ans = canWin(cur);

cur[i] = cur[i - 1] = '+';//回溯

if (!ans)

return memo[h]=true;

//下一个不存在答案 那么上一个就为true

//博弈论

}

}

return memo[h]=false;

}

};

lc156

从下到上 重连后 记得置空

tnode* dfs 在找最左节点的过程中重连

class Solution {

public:

TreeNode* upsideDownBinaryTree(TreeNode* root)

{

if(!root || !root->left) return root;

auto dfs=[&](this auto&& dfs,TreeNode* node)->TreeNode*

{

if(!node->left)

return node;

auto mxl=dfs(node->left);

node->left->left=node->right;

node->left->right=node;

++//从下到上 连好了后置空++

node->left=nullptr;

node->right=nullptr;

++return mxl;++

};

return dfs(root);

//最左边 节点为根

}

};

相关推荐
云里雾里!7 小时前
LeetCode 744. 寻找比目标字母大的最小字母 | 从低效到最优的二分解法优化
算法·leetcode
一条大祥脚7 小时前
26.1.3 快速幂+容斥 树上dp+快速幂 带前缀和的快速幂 正序转倒序 子序列自动机 线段树维护滑窗
数据结构·算法
二狗哈7 小时前
czsc入门5: Tick RawBar(原始k线) NewBar (新K线)
算法·czsc
Tisfy7 小时前
LeetCode 0865.具有所有最深节点的最小子树:深度优先搜索(一次DFS + Python5行)
算法·leetcode·深度优先·dfs·题解
Q741_1477 小时前
C++ 队列 宽度优先搜索 BFS 力扣 429. N 叉树的层序遍历 C++ 每日一题
c++·算法·leetcode·bfs·宽度优先
Yzzz-F7 小时前
P4145 上帝造题的七分钟 2 / 花神游历各国[线段树 区间开方(剪枝) + 区间求和]
算法·机器学习·剪枝
Zzz不能停7 小时前
堆排序算法及大小堆区别
数据结构·算法
zd8451015007 小时前
stm32f407 电机多轴联动算法
stm32·单片机·算法
代码游侠7 小时前
应用——Linux FrameBuffer图形显示与多线程消息系统项目
linux·运维·服务器·开发语言·前端·算法
Eloudy7 小时前
矩阵张量积(Kronecker积)的代数性质与定理
算法·量子计算