1144. Decrease Elements To Make Array Zigzag
给定一个数组,只能采用减一操作,判断最多需要减多少次,使得数组内数字满足zigzag array
,即中间元素比两边大或中间元素比两边小
既然最后的结果只有两种,即中间大或中间小,那么分别对两种情况进行计算,取小值即可
class Solution {
public:
int calcuRes(vector<int> v, int begin)
{
int id = begin + 1;
int res = 0;
while (id < v.size() - 1)
{
if (v[id - 1] >= v[id])
res += (v[id - 1] - v[id] + 1);
if (v[id + 1] >= v[id])
{
res += (v[id + 1] - v[id] + 1);
v[id + 1] = v[id + 1] - (v[id + 1] - v[id] + 1);
}
id += 2;
}
if (id == v.size() - 1 && v[id - 1] >= v[id]) res += (v[id - 1] - v[id] + 1);
return res;
}
int movesToMakeZigzag(vector<int>& nums) {
if (nums.size() == 1) return 0;
int res1 = calcuRes(nums, 0), res2 = 0;
if (nums[1] >= nums[0])
{
res2 += nums[1] - nums[0] + 1;
nums[1] = nums[0] - 1;
}
res2 += calcuRes(nums, 1);
return min(res1, res2);
}
};
1145. Binary Tree Coloring Game
给定一个二叉树,根节点为root,共有n个节点,每个节点数字唯一,从1~n,当前值为x的节点被选中涂红,选择另外一个节点涂蓝,此后两人轮流选择各自颜色的相邻节点(包括儿子和父节点)涂色,直至两边都无法涂色,判断蓝色节点是否多于红色节点
对于涂蓝节点的选择,为了掐断红色节点的下一轮选择,有两种方案,如下图所示,打勾的是已选的红色节点,涂黑的是蓝色节点
可以选择红色节点的 父节点,使下一轮红色只能往孩子延伸
也可以左右子节点中,节点数较多的那个支路
因此递归遍历整棵树,对找到值为x的节点计算左右子节点数即可
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool btreeGameWinningMove(TreeNode* root, int n, int x)
{
if(root == NULL) return false;
int maxn = 0;
countChild(root, x, n, maxn);
return maxn > n - maxn;
}
int countChild(TreeNode* root, int x, int n, int& maxn)
{
if (root == NULL) return 0;
int l = countChild(root->left, x, n, maxn);
int r = countChild(root->right, x, n, maxn);
if(root->val == x)
{
maxn = max(l, r);
maxn = max(maxn, n - l - r - 1);
}
return l + r + 1;
}
};
1146. Snapshot Array
实现一个SnapshotArray类,包含:
构造函数为构造一个长为length的数组array
set(index, val): array[index]=val
snap(): 对当前的array做个备份,并返回当前备份数
get(index, snap_id): 返回第snap_id次备份中array[index]
若直接初始化一个snap_id大小的数组,每个snap_id对应一个大小为length的array,尽管时间上可以做到O(1),但空间太浪费(snap_id可能很大),会MLE,因此可以创建length大小的数组,初始化全0,每个数组中存放已被set过的index(未set过的必然为0)
最后get时只要找到对应snap_id,若对应snap_id不存在,说明该index在一段时间内被连续snap,未更新,因此只要返回其最后一次被更新时的值即可
class SnapshotArray {
private:
map<int, vector<pair<int, int>>> snapMap;
int snapid;
public:
SnapshotArray(int length) {
snapid = 0;
for(int i = 0; i < length; ++i)
snapMap[i].emplace_back(make_pair(-1, 0));
}
void set(int index, int val) {
if(snapMap[index].back().first == snapid)
snapMap[index].back().second = val;
else snapMap[index].emplace_back(make_pair(snapid, val));
}
int snap() {
return snapid++;
}
int get(int index, int snap_id) {
auto it = lower_bound(snapMap[index].begin(), snapMap[index].end(), make_pair(snap_id + 1, -1));
--it;
return it->second;
int tar = 0;
int i = 0;
for(; i < snapMap[index].size(); ++i)
if(snapMap[index][i].first == snapid - 1)
{
tar = i;
break;
}
if(i == snapMap[index].size()) return snapMap[index].back().second;
return snapMap[index][tar].second;
}
};
1147. Longest Chunked Palindrome Decomposition
给定一个字符串,将其分割为k个子串,使子串
,求出最大的k值
先将每个字符出现的位置保存,每次匹配当前字符对应的位置,判断是否可以匹配,直至匹配完整个字符串,递归判断即可
class Solution {
public:
int longestDecomposition(string text) {
if(text.length() == 1) return 1;
map<char, vector<int>> hash;
for (int i = 0; i < text.length(); ++i)
hash[text[i]].emplace_back(i);
int maxn = 1;
decompositionHelper(text, hash, 0, text.length() - 1, 0, maxn);
return maxn;
}
void decompositionHelper(string text, map<char, vector<int>>& hash, int begin, int end, int cur, int& maxn)
{
if (begin > end)
{
maxn = max(maxn, cur);
return ;
}
char c = text[begin];
for (int i = hash[c].size() - 1; i >= 0; --i)
{
if (hash[c][i] > end || hash[c][i] <= begin) continue;
int j = hash[c][i];
for (; j <= end; ++j)
{
if (text[j] != text[j - hash[c][i] + begin]) break;
}
if (j == end + 1)
decompositionHelper(text, hash, begin + (end - hash[c][i] + 1), hash[c][i] - 1, cur + 2, maxn);
}
maxn = max(maxn, cur + 1);
}
};