第一题
题目:
解法:打卡题。
第二题
题目:
解法:跟之前周赛的求最大公约数的题目是一个思路:
class Solution {
public:
int subarrayLCM(vector<int>& nums, int k) {
int n=nums.size();
int ans=0;
for(int i=0;i<n;i++){
long long g=1;
for(int j=i;j<n;j++){
g=lcm(g,nums[j]);//lcm为求两数最大公倍数的内置函数
if(g==k){
ans++;
}
else if(g>k){ //>k说明肯定不符合了,直接break
break;
}
}
}
return ans;
}
};
第三题
题目:
解法:第三题的本质是对给定范围的数组,求出通过最少多少次两两交换可以使范围内数组按顺序排列。首先提出结论,如果几个数形成了置换环(即对于这几个数,它们在数组原位置和排序后的位置形成了独立的互相干扰),则这几个数需要置换环长度-1次的两两对换才能实现排序,对于一个长度为n的需要排序的数组,由于所有的置换环(位置本身正确的一个数形成一个环,1-1=0不需要对换)长度加起来n,所以总的调换次数等于n-置换环个数。
/**
* 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:
int minimumOperations(TreeNode* root) {
int ans=0;
function <int(vector <int>)> getnum=[&](vector <int> nums){//对于某个数组求出对换次数
vector<int> nums1(nums);
sort(nums1.begin(),nums1.end());
unordered_map<int,int> m;
int len = nums.size();
for (int i = 0; i < len; i++){
m[nums1[i]] = i;//建立每个元素与其应放位置的映射关系
}
int loops = 0;//置换环个数
vector<bool> flag(len,false);//建立一个判断置换的数组
//找出置换环的个数
for (int i = 0; i < len; i++){
if (!flag[i]){//已经访问过的位置不再访问
int j = i;
while (!flag[j]){
flag[j] = true;
j = m[nums[j]];//原序列中j位置的元素在有序序列中的位置
}
loops++;
}
}
return len - loops;//n-置换环个数
};
queue <TreeNode*> duilie;
duilie.push(root);
int rest=1;
int nextrest=0;
int lun=0;
while(duilie.size()!=0){
vector<int >tempv;
rest=lun==0?1:nextrest;
nextrest=0;
while(rest>0){
TreeNode *temp=duilie.front();
duilie.pop();
rest--;
tempv.push_back(temp->val);
if(temp->left!=nullptr){
duilie.push(temp->left);
nextrest++;
}
if(temp->right!=nullptr){
duilie.push(temp->right);
nextrest++;
}
}
lun++;
if(tempv.size()!=0){
ans+=getnum(tempv);
}
}
return ans;
}
};
第四题
题目:
解法:定义f[i]表示s[0…i−1]中的不重叠回文子字符串的最大数目,采用中心拓展法枚举,即从一个数往左右拓展,如果左右相等就是一个回文串。特别地,定义 f[0]=0,方便表示空字符串。
class Solution {
public:
int maxPalindromes(string s, int k) {
int n = s.length(), f[n + 1];
memset(f, 0, sizeof(f));
for (int i = 0; i < 2 * n - 1; ++i) {
int l = i / 2, r = l + i % 2; // 中心扩展法,如果回文串长度为奇数,那么中间就只有一个数l=r,如果为偶数l=r-1
f[l + 1] = max(f[l + 1], f[l]);//不选这个数
for (; l >= 0 && r < n && s[l] == s[r]; --l, ++r)
if (r - l + 1 >= k) {
f[r + 1] = max(f[r + 1], f[l] + 1);
break;
}
}
return f[n];
}
};
以上题解只是对灵神题解的总结,非原创捏1