首页 > 其他分享 >Leetcode 373周赛

Leetcode 373周赛

时间:2023-11-26 18:58:43浏览次数:29  
标签:周赛 int det ++ vector vec rem 373 Leetcode

周赛链接:https://leetcode.cn/contest/weekly-contest-373/

100139. 循环移位后的矩阵相似检查

不需要判断奇数还是偶数,题目要求最后两个矩阵是否相同,那么向左循环移动和向右循环移动意义是一样的

奇数行右移k次,$$a[i]==a[(i + k) % size]$$

偶数行左移k次,$$a[i] == a[(i - k) % size]$$

向右循环移动即可,如果某个位置不相同,直接返回false

class Solution {
public:
    bool areSimilar(vector<vector<int>>& mat, int k) {
        bool flag = true;
        for (auto row : mat) {
            for (int i = 0; i < row.size(); i ++) {
                if (row[i] != row[(i + k) % row.size()]) {
                    return false;
                }
            }
        }
        return flag;
    }
};

100142. 交换得到字典序最小的数组

image-20231126170232811

模拟,找规律,找联系。

对于每个数字,如果存在另外一个数字,跟他相差,小于等于limit,那么就是一个连通块,这样就能互相交换。

把nums排序后,需要找到一个最长的连续段,相邻数字的差是 <= limit

这一整段对应的下标集合,这些位置之间是可以随意排序的。

本题用到一个经典结论。

把序列中的每个元素看成图中的一个点,如果两个元素可以相互交换,则在两个元素之间连一条边。结论:处于同一连通块内的所有元素可以通过若干次操作排成任意顺序。

排序

image-20231126170352069

把原序列,从小到大排好序,为了让答案的字典序最小,每个子段从小到大排序即可。

参考题解

https://leetcode.cn/problems/make-lexicographically-smallest-array-by-swapping-elements/solutions/2542306/pai-xu-by-tsreaper-a8wl/

class Solution {
public:
    vector<int> lexicographicallySmallestArray(vector<int>& nums, int limit) {
        int n = nums.size();
        typedef pair<int, int> pii;
        // 把所有元素从小到大排序,要记录一下原来的下标
        vector<pii> vec;
        for (int i = 0; i < n; i ++) vec.push_back(pii(nums[i], i));
        sort(vec.begin(), vec.end());

        // for (auto x : vec) {
        //     cout << x.first << ' ';
        // }
        // cout << endl;

        // 把所有元素切成若干子段,子段内的相邻元素之差不超过 limit
        /**
        * segs 二维数组
        **/
        vector<vector<pii>> segs;
        int last = -limit;
        for (int i = 0; i < n; i ++) {
            if (vec[i].first - last > limit) segs.push_back({}); // 这里插入一个空行,切割
            segs.back().push_back(vec[i]);
            last = vec[i].first; // 更新
        }

        vector<int> ans(n);
        // 对每个子段分别从小到大排序,填回序列中
        for (auto &seg : segs) {
            vector<int> pos; // 每次新建一个数组,保存当前这层的下标
            for (auto &p : seg) pos.push_back(p.second); // 把每一组的下标保存好
            sort(pos.begin(), pos.end()); // seg 里面,每个组都是有序的,这里把下标排好序,让每个分组都可以互相插入进去
            // 这样整体字典序就最小了
            // for (auto x : pos) {
            //     cout << x << ' ';
            // }
            // cout << endl;
            for (int i = 0; i < seg.size(); i ++) ans[pos[i]] = seg[i].first;
        }


        return ans;
    }
};

100134. 统计美丽子字符串 I

100132. 统计美丽子字符串 II

参考题解:

https://leetcode.cn/problems/count-beautiful-substrings-ii/solutions/2542302/mei-ju-by-tsreaper-1fi2/

class Solution {
public:
    long long beautifulSubstrings(string s, int K) {
        // 判断字符 c 是不是元音
        auto check = [&](char c) {
            return c == 'a' || c == 'e' || c == 'i' || c == 'o'
                || c == 'u';
        };
        int n = s.size();

        // valid 里保存所有满足 w^2 mod k = 0 的 w,这里是暴力枚举。
        vector<int> valid;
        for (int rem = 0; rem < K; rem ++) {
            if (rem * rem % K == 0) valid.push_back(rem);
        }
        long long ans = 0;
        unordered_map<int, unordered_map<int ,int>> mp;
        // 用长度为 0 的前缀初始化哈希表
        mp[0][0] = 1;
        // det: 前缀中元音 - 辅音的值
        // cnt: 前缀中元音的数量
        int det = 0, cnt = 0;
        // 枚举子串右端点
        for (int i = 0; i < n;i ++) {
            if (check(s[i])) det ++, cnt ++;
            else det --;
            // 枚举 w
            for (int rem : valid) {
                int t = (cnt - rem + K) % K;
                if (mp[det].count(t)) ans += mp[det][t];
            }
            // 用以 i 为结尾的前缀更新hash表
            mp[det][cnt % K] ++;
        }
        return ans;
    }
};

标签:周赛,int,det,++,vector,vec,rem,373,Leetcode
From: https://www.cnblogs.com/lukelmouse/p/17857687.html

相关文章

  • leetcode hot100-03 移动零
    移动零地址:https://leetcode.cn/classic/problems/move-zeroes/description/难点:在原数组的基础上进行移动保持相对顺序思考过程:思考过程:一开始没有考虑顺序的问题记录最后一个不是0的位置从左遍历数据如果为0则将数据与最后一位不是0的数据交换最后不是0的数据更......
  • 牛客周赛Round20. C 小红的01串构造 (纯构造
    packagenewCode.周赛Round20;importjava.util.Scanner;publicclassC{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intn=sc.nextInt(),k=sc.nextInt(),t=sc.nextInt();if(t>=k||2......
  • 牛客周赛Round20. A 赝品
    packagenewCode.周赛Round20;importjava.util.Arrays;importjava.util.Scanner;publicclassA{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intn=sc.nextInt();int[]a=newint[n+10];......
  • LeetCode 354. (经典问题) 俄罗斯套娃信封问题 (俄罗斯套娃模型 + 最长下降子序列
    packageleetcode;importjava.util.Arrays;publicclasslec154{/***首先是思路来源:https://leetcode.cn/problems/russian-doll-envelopes/solutions/19681/zui-chang-di-zeng-zi-xu-lie-kuo-zhan-dao-er-wei-er/*思路:先按照宽度降序(升序)接着......
  • 【11月LeetCode组队打卡】Task4--BinarySearchTree
    Review有数值有序树:lch<root<rch递归和迭代遍历不同于普通二叉树搜索BST700.二叉搜索树中的搜索有:返回以存储val节点为根的子树无:NULLAC1:递归参数和返回值:根节点&待寻值节点终止条件:根为空||匹配到val单层逻辑:有序树:从左到右搜索......
  • LeetCode二叉树小题目
    Q1将有序数组转换为二叉搜索树题目大致意思就是从一个数组建立平衡的二叉搜索树。由于数组以及进行了升序处理,我们只要考虑好怎么做到平衡的。平衡意味着左右子树的高度差不能大于1。由此我们可以想着是否能用类似二分+递归来解决。如果left>right,直接返回nullpter否则......
  • [LeetCode] 1630. Arithmetic Subarrays
    Asequenceofnumbersiscalledarithmeticifitconsistsofatleasttwoelements,andthedifferencebetweeneverytwoconsecutiveelementsisthesame.Moreformally,asequencesisarithmeticifandonlyifs[i+1]-s[i]==s[1]-s[0]forallvalid......
  • LeetCode之二叉树
    发现新天地,欢迎访问Cr不是铬的个人网站平衡二叉树做这一道题目我们要考虑到平衡二叉树的定义。也就是一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1。关于一个结点的高度计算我们很容易用递归得出,那么我们用递归遍历加上这个判断条件即可.classSolution{pu......
  • acwing 第 130 场周赛  (前缀和,dfs,对不同边的处理)
      #include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<climits>usingnamespacestd;typedeflonglongLL;constintN=5010;intn;inta[N];LLs[N];LLget(intl,intr){return......
  • 【11月LeetCode组队打卡】Task3--BinaryTree
    树基本术语:节点的度:叶子节点=0分支节点:含有的子树个数节点关系:父,子,兄节点层次:根节点:1floor路径:两节点间经过的节点序列路径长度:路径上的边数树的分类:节点子树是否可以互换位置:有序树:从左到右各子树依次有序(不能互换无序树二叉......