话不多数直接上题:
对于第一题直接模拟即可:
2469. 温度转换 - 力扣(Leetcode)https://leetcode.cn/problems/convert-the-temperature/
class Solution {
public:
vector<double> convertTemperature(double celsius) {
return {celsius+273.15,celsius*1.80+32.00};
}
};
第二题主要采用了两种方法:
1 <= nums.length <= 1000
1 <= nums[i], k <= 1000
第一种方法暴力即可,分析题目给出的条件发现此题采用暴力明显可以保证2s内执行完毕,所以首先尝试用暴力解决此问题,代码如下:
class Solution {
public:
int subarrayLCM(vector<int>& nums, int k) {
int n=nums.size();
int res=0;
for(int i=0;i<n;++i){
long long lcdNum=nums[i];
for(int j=i;j<n;++j){
lcdNum=lcm(lcdNum,nums[j]);
if(lcdNum==k) res++;
else if(lcdNum>k) break;
}
}
return res;
}
};
这里代用else if的条件对于数据进行一部分剪枝。
时间复杂度 O(n^2 logk) (n是nums数组的长度,lcm的倍增次数是 O(logk))
第二种方法:
class Solution {
public:
int ret = 0, i, j, pre = 1, loc = -1, cur = 1;
for (i = 0; i < nums.size(); i ++){
pre = lcm(pre, nums[i]) ;
// 求 cur == k 的最大的左边界
if (k % pre == 0){// 说明此时pre是k的一个公因数
j = i ;
cur=nums[j];
while(j > loc && k != cur){
j -- ;
if (j <= loc) break ;
cur = lcm(nums[j], cur) ;
}
ret += j - loc ;
}else {
loc = i ;
pre = 1 ;
}
}
return ret ;
}
};
1. 首先是计算以i为右边界的 最小公倍数pre; 2.1 当k % pre == 0 ; 求 cur == k的最大的左边界; 以i为右边界的符合要求的连续序列个数: j - loc ;
2. 所求的结果 ret += j - loc ;
根据lcd的性质我们很容易发现随着子数组右窗口的不断增加,最小公倍数一定是规律变化的(要么不变,要么扩大2倍及以上),这样我们只要维护一个窗口来实现该窗口下的最小公倍数是k即可。
此题是要维护树中的每一层保证树的每一层都是经过从小到大排序的,求最小操作数,这么一分析我们此题可以分解成两个小问题:
1. 提取每一层树的元素组成的一维数组存入二维数组中存储;
2. 对每一层数的数组进行归位(置换环问题);
关于置换环问题可以看这个网站:
代码如下:
class Solution {
public:
int minimumOperations(TreeNode* root) {
vector<vector<int>> tree;
function<void()> bfs=[&](){
queue<TreeNode*> que;
if(!root) return;
que.push(root);
while(!que.empty()){
int size=que.size();
vector<int> path;
for(int i=0;i<size;++i){
TreeNode* node=que.front();
path.push_back(node->val);
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
tree.push_back(path);
}
};
int res=0;
bfs();
for(auto &subtree:tree){
vector<int> target=subtree;
unordered_map<int,int> idx;
int temp=0;
sort(target.begin(),target.end());
for(auto i:target) idx[i]=temp++;
for (int i = 0; i < subtree.size(); i++) {
// 置换归位
// 注意别写成 if 了
while(subtree[i] != target[i]) {
swap(subtree[i], subtree[idx[subtree[i]]]);
res++;
}
}
}
return res;
}
};
这里特别注意for循环下的while不能写成if ,举一个例子即可理解,[2,3,4,1] 这个数组如果采用if 语句最后归位后的数组就是 [3,2,1,4] ,很显然这个数组如果采用if 无法进行归位。