力扣319周周赛(补)

话不多数直接上题:

对于第一题直接模拟即可:

2469. 温度转换 - 力扣(Leetcode)icon-default.png?t=M85Bhttps://leetcode.cn/problems/convert-the-temperature/

class Solution {
public:
    vector<double> convertTemperature(double celsius) {
        return {celsius+273.15,celsius*1.80+32.00};
    }
};

2470. 最小公倍数为 K 的子数组数目 - 力扣(Leetcode)icon-default.png?t=M85Bhttps://leetcode.cn/problems/number-of-subarrays-with-lcm-equal-to-k/

第二题主要采用了两种方法:

  • 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即可。

2471. 逐层排序二叉树所需的最少操作数目 - 力扣(Leetcode)icon-default.png?t=M85Bhttps://leetcode.cn/problems/minimum-number-of-operations-to-sort-a-binary-tree-by-level/

此题是要维护树中的每一层保证树的每一层都是经过从小到大排序的,求最小操作数,这么一分析我们此题可以分解成两个小问题:

1. 提取每一层树的元素组成的一维数组存入二维数组中存储;

2. 对每一层数的数组进行归位(置换环问题);

关于置换环问题可以看这个网站:

Minimum number of swaps required to sort an array - GeeksforGeeksicon-default.png?t=M85Bhttps://www.geeksforgeeks.org/minimum-number-swaps-required-sort-array/

代码如下:

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 无法进行归位。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值