做周赛的时候,注意力很集中哈哈,enjoy这个感觉,木有浮躁~
做完之后看大佬写的代码,惊叹且学习了新思路和方法,很开森~
https://leetcode-cn.com/contest/weekly-contest-199/problems/shuffle-string/
给你一个字符串 s 和一个 长度相同 的整数数组 indices 。
请你重新排列字符串 s ,其中第 i 个字符需要移动到 indices[i] 指示的位置。
返回重新排列后的字符串。
输入:s = “codeleet”, indices = [4,5,6,7,0,2,1,3]
输出:“leetcode”
解释:如图所示,“codeleet” 重新排列后变为 “leetcode” 。
class Solution {
public:
string restoreString(string s, vector<int>& indices) {
string res = s;
for (int i = 0; i < indices.size(); i++) {
res[indices[i]] = s[i];
}
return res;
}
};
https://leetcode-cn.com/contest/weekly-contest-199/problems/bulb-switcher-iv/
房间中有 n 个灯泡,编号从 0 到 n-1 ,自左向右排成一行。最开始的时候,所有的灯泡都是 关 着的。
请你设法使得灯泡的开关状态和 target 描述的状态一致,其中 target[i] 等于 1 第 i 个灯泡是开着的,等于 0 意味着第 i 个灯是关着的。
有一个开关可以用于翻转灯泡的状态,翻转操作定义如下:
选择当前配置下的任意一个灯泡(下标为 i )
翻转下标从 i 到 n-1 的每个灯泡
翻转时,如果灯泡的状态为 0 就变为 1,为 1 就变为 0 。
返回达成 target 描述的状态所需的 最少 翻转次数。
示例 1:
输入:target = “10111”
输出:3
解释:初始配置 “00000”.
从第 3 个灯泡(下标为 2)开始翻转 “00000” -> “00111”
从第 1 个灯泡(下标为 0)开始翻转 “00111” -> “11000”
从第 2 个灯泡(下标为 1)开始翻转 “11000” -> “10111”
至少需要翻转 3 次才能达成 target 描述的状态
class Solution {
public:
string targetStr;
int minFlips(string target) {
targetStr = target;
return bfs();
}
int bfs() {
queue<string> temps;
map<string, bool> exists;
string tempStr = "";
int n = targetStr.length();
for (int i = 0; i < n; i++)
tempStr += '0';
temps.push(tempStr);
exists.insert(make_pair(tempStr, true));
int depth = 0;
while(!temps.empty()) {
int levelNum = temps.size();
for (int k = 0; k < levelNum; k++) {
tempStr = temps.front();
temps.pop();
//cout << tempStr << endl;
if (tempStr == targetStr)
return depth;
for (int i = n-1; i >= 0; i--) {
if (tempStr[i] == '1')
tempStr[i] = '0';
else
tempStr[i] = '1';
if (!exists.count(tempStr)) {
temps.push(tempStr);
exists.insert(make_pair(tempStr, true));
}
}
}
depth++;
}
return depth;
}
};
class Solution {
public:
int minFlips(string target) {
//就说有巧妙的方法,我一根筋的在bfs
// 如果位置1,证明要翻转,从左到右逐渐趋紧最优解
//101
//
int cur = 0;
int res = 0;
for (int i = 0; i < target.length(); i++) {
int curPos = target[i] - '0'; //0 or 1
if (curPos ^ cur == 1) { // 当前异或是1,证明变成当前操作需要一次翻转,而且之后的每一位都变成了翻转后的值
cur = cur ^ 1; // 异或操作 00=1
res ++;
}
}
return res;
}
};
https://leetcode-cn.com/contest/weekly-contest-199/problems/number-of-good-leaf-nodes-pairs/
5474. 好叶子节点对的数量
给你二叉树的根节点 root 和一个整数 distance 。
如果二叉树中两个 叶 节点之间的 最短路径长度 小于或者等于 distance ,那它们就可以构成一组 好叶子节点对 。
返回树中 好叶子节点对的数量 。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<TreeNode*> leaves;
int countPairs(TreeNode* root, int distance) {
//暴力法就是先找到所有的叶子节点n,然后任意两个最短路径如果小于等于distance
traverse(root);
int res = 0;
for (int i = 0; i < leaves.size(); i++) {
for (int j = i+1; j < leaves.size(); j++) {
TreeNode* leaf1 = leaves[i];
TreeNode* leaf2 = leaves[j];
TreeNode* par = lowestCommonAncestor(root, leaf1, leaf2);
int disTemp = getLength(leaf1, leaf2, par);
//cout << leaf1->val << " " << leaf2->val << ": " << disTemp << endl;
if ( disTemp <= distance)
res++;
}
}
return res;
}
void traverse(TreeNode* root) {
if (root == NULL)
return;
traverse(root->left);
traverse(root->right);
if (root->left == NULL && root->right== NULL)
leaves.push_back(root);
}
int getLength(TreeNode* leaf1, TreeNode* leaf2, TreeNode* par) {
int res = 0;
queue<TreeNode*> nodes;
nodes.push(par);
int len1 = -1;
int len2 = -1;
int depth=0;
while(!nodes.empty()) {
int n = nodes.size();
for (int i = 0; i < n; i++) {
TreeNode* t = nodes.front();
nodes.pop();
if (t == leaf1)
len1 = depth;
if (t == leaf2)
len2 = depth;
if (len1 != -1 && len2 != -1)
break;
if (t->left != NULL) {
nodes.push(t->left);
}
if (t->right != NULL) {
nodes.push(t->right);
}
}
depth++;
}
return len1+len2;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){
//发现目标节点则通过返回值标记该子树发现了某个目标节点
if (root == NULL || root == p || root == q) {
return root;
}
//查看左子树中是否有目标节点,没有为null
TreeNode* left = lowestCommonAncestor(root->left, p, q);
//查看右子树中是否有目标节点,没有为null
TreeNode* right = lowestCommonAncestor(root->right, p, q);
//都不为空,则说明左右子树都有目标节点,则公共祖先就是本身。
if (left != NULL && right != NULL) {
return root;
}
return left == NULL ? right : left;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<TreeNode*> leaves;
vector<string> paths;
int countPairs(TreeNode* root, int distance) {
//暴力法就是先找到所有的叶子节点n,然后任意两个最短路径如果小于等于distance,leaves其实没必要
traverse(root, "");
int res = 0;
for (int i = 0; i < leaves.size(); i++) {
for (int j = i+1; j < leaves.size(); j++) {
int disTemp = paths[i].length() + paths[j].length();
for (int k = 0; k < paths[i].length() && k < paths[j].length(); k++) {
if (paths[i][k] == paths[j][k])
disTemp-=2;
else
break;
}
if ( disTemp <= distance)
res++;
}
}
return res;
}
void traverse(TreeNode* root, string path) {
if (root == NULL)
return;
traverse(root->left, path+'0');
traverse(root->right, path+'1');
if (root->left == NULL && root->right== NULL) {
leaves.push_back(root);
paths.push_back(path);
}
}
}