力扣周赛319 笔记

力扣周赛319笔记

  • 第一题
  • 第二题
  • 第三题
  • 第四题

第一题

题目

力扣周赛319 笔记_第1张图片

解法:打卡题。

第二题

题目:
力扣周赛319 笔记_第2张图片

解法:跟之前周赛的求最大公约数的题目是一个思路:

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;
    }
};

第三题

题目

力扣周赛319 笔记_第3张图片

解法:第三题的本质是对给定范围的数组,求出通过最少多少次两两交换可以使范围内数组按顺序排列。首先提出结论,如果几个数形成了置换环(即对于这几个数,它们在数组原位置和排序后的位置形成了独立的互相干扰),则这几个数需要置换环长度-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;
    }
};

第四题

题目
力扣周赛319 笔记_第4张图片

解法:定义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


  1. 灵神b站题解 ↩︎

你可能感兴趣的:(leetcode,算法,数据结构)