Leetcode周赛373总结

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

  • 题目链接

  • 解题思路:

    • 就硬模拟吧 然后判断循环移位后的矩阵和之前是否相同
  • 解题代码:


class Solution {
public:
    bool areSimilar(vector<vector<int>>& mat, int k) {
        int m = mat.size();
        int n = mat[0].size();
        k %= n;
        auto reverse = [&](int i, int l, int r)
        {
            while(l <= r)
            {
                swap(mat[i][l], mat[i][r]);
                l += 1;
                r -= 1;
            }
        };
        for(int i = 0; i < m; i++)
        {
            vector<int> src = mat[i];
            reverse(i, 0, n-1);
            if(i & 1)
            {    
                reverse(i, 0, k-1);
                reverse(i, k, n-1);
            }
            else
            {
                reverse(i, n-k, n-1);
                reverse(i, 0, n-k-1);
            }
            if(src != mat[i])
                return false;
        }
        return true;
    }
};

  • 更简洁的写法,不需要实际移动,只需要判断对应元素是否相同

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

Q2 统计美丽子字符串I

  • 题目链接

  • 解题思路:

    • 该题可以用暴力的方法来做
    • 直接去枚举每个子字符串,判断是否满足条件即可
  • 解题代码:


class Solution {
public:
    int beautifulSubstrings(string s, int k) {
        int n = s.size();
        int ans = 0;
        for(int i = 0; i < n; i++)
        {
            int vowels = 0, consonants = 0;
            for(int j = i; j < n; j++)
            {
                if(s[j] == 'a' || s[j] == 'e' || s[j] == 'i' || s[j] == 'o' || s[j] == 'u')
                    vowels += 1;
                else
                    consonants += 1;
                if(vowels == consonants && (vowels * consonants) % k == 0)
                    ans += 1;
            }
        }
        return ans;
    }
};

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

  • 题目链接

  • 解题思路:

    • 首先将nums连带下标一起进行排序
    • 根据nums[j] - nums[i] <= limit这个条件,将原数组分成多个部分
    • 统计每个部分内的下标,将每部分内较小的数放在较小的下标
  • 解题代码:


class Solution {
public:
    vector<int> lexicographicallySmallestArray(vector<int>& nums, int limit) {
       
        int n = nums.size();
        vector<int> ans(n);
        vector<pair<int, int>> items;
        for(int i = 0; i < n; i++)
            items.push_back({nums[i], i});
        sort(items.begin(), items.end(), [](const pair<int, int>& a, const pair<int, int>& b)
        {
            return a.first < b.first;
        });
        auto func = [&](int l, int r)
        {
            priority_queue<int, vector<int>, greater<int>> pq;
            for(int i = l; i <= r; i++)
                pq.push(items[i].second);
            int idx = l;
            while(!pq.empty())
            {
                int cur = pq.top();
                pq.pop();
                ans[cur] = items[idx].first;
                idx += 1;
            }
        };
        for(int i = 0; i < n; i++)
        {
            int j = i + 1;
            while(j < n && items[j].first - items[j-1].first <= limit)
                j += 1;
            func(i, j-1);
            i = j-1;
        }
        return ans;
    }
};

Q4 统计美丽子字符串II

  • 题目链接
  • 解题思路:
    • 设字串长度为L,需要满足 L^2 是 4k的倍数

      • (L/2)^2 % k = 0 => (L/2)^2 = mk => L^2 = 4mk => L^2 % (4k) = 0
      • 找满足条件的最小L
      • 假设最小L = k’,那么子字符串的长度L应该满足L % k’ = 0
    • 元音字母个数 = 辅音字母个数

      • 元音字母 = 1, 辅音字母 = -1
      • 子数组元素和等于0即可满足条件
    • 前缀和处理子数组元素和

      • [j, i) = sum[i] - sum[j] = 0
      • 需要满足sum[i] = sum[j]
      • 同时需要满足(i - j) % k’ = 0 => i % k’ = j % k’
    • 哈希表统计(i%k’, sum[i])的出现次数


class Solution {
public:
    long long beautifulSubstrings(string s, int k) {
        int d = 1;
        while(1)  
        {
            if(d * d % (4 * k) == 0)
            {
                k = d;
                break;
            }
            d += 1;
        }
        int n = s.size();
        vector<int> nums(n);
        for(int i = 0; i < n; i++)
        {
            if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u')
                nums[i] = 1;
            else
                nums[i] = -1;
        }
        vector<int> sum(n+1, 0);
        for(int i = 1; i <= n; i++)
            sum[i] = sum[i-1] + nums[i-1];
        map<pair<int, int>, int> m;
        long long ans = 0;
        for(int i = 0; i <= n; i++)
        {
            ans += m[{i%k, sum[i]}];
            m[{i%k, sum[i]}] += 1;
        }
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值