 LeetCode 310th Weekly Contest
LeetCode 310th Weekly Contest
  # A
# 题目
2404. 出现最频繁的偶数元素 - 力扣(LeetCode) (opens new window)
# 思路
# 1. 枚举
用数组或者哈希表统计每个数字出现的次数,然后枚举以此判断即可
# 代码
class Solution {
public:
    int mostFrequentEven(vector<int>& nums) {
        std::map<int, int> cnt;
        for (auto x : nums) cnt[x] ++;
        int maxcnt = -1, maxv = -1;
        for (auto [x, cc] : cnt) {
            if (x % 2 == 0 && cc > maxcnt) maxv = x, maxcnt = cc;
        }
        return maxv;
    }
};
// Make sure to add code blocks to your code group
# B
# 题目
2405. 子字符串的最优划分 - 力扣(LeetCode) (opens new window)
# 思路
# 1. 枚举
从头往后枚举
# 代码
class Solution {
public:
  int partitionString(string s) {
      int res = 0;
      std::vector<bool> pos(26);
      for (auto x : s) {
          if (pos[x - 'a']) {
              res ++;
              for (int i = 0; i < 26; i ++) pos[i] = 0;
              pos[x - 'a'] = 1;
          } else {
              pos[x - 'a'] = 1;
          }
      }
      return res + 1;
  }
};
// Make sure to add code blocks to your code group
# C
# 题目
2406. 将区间分为最少组数 - 力扣(LeetCode) (opens new window)
# 思路
# 1.贪心 + 优先队列
先对序列按左端点进行排序,然后用小根堆维护最小的右端点,每次取最小的右端点和当前的区间进行比较。如果没有相交,就取出堆顶并放入当前区间的右端点,表示合并到一个组中;否则有相交,则直接入堆当前区间的右端点即可。最终答案便是优先队列的长度。
# 代码
class Solution {
public:
  int minGroups(vector<vector<int>>& intervals) {
      std::sort(intervals.begin(), intervals.end());
      int n = intervals.size();
      std::priority_queue<int, std::vector<int>, std::greater<int>> pq;
      for (int i = 0; i < n; i ++) {
          if (pq.empty() || pq.top() >= intervals[i][0]) pq.emplace(intervals[i][1]);
          else {
              pq.pop();
              pq.emplace(intervals[i][1]);
          }
      }
      return pq.size();
  }
};
// Make sure to add code blocks to your code group
# 2.差分
通过差分,可以用 dif[left] ++, dif[right + 1] --;。由于差分数组的前缀和等于单点的值,我们只需要遍历差分数组求前缀和,便能得到每个点的区间重叠个数,答案取其最大值即可
# 代码
class Solution {
public:
  int minGroups(vector<vector<int>>& intervals) {
      int n = intervals.size();
      std::vector<int> dif(1e6 + 2);
      for (auto x : intervals) {
          dif[x[0]] ++, dif[x[1] + 1] --;
      }
      int res = 0, sum = 0;
      for (auto x : dif) {
          res = std::max(res, sum += x);
      }
      return res;
  }
};
// Make sure to add code blocks to your code group
# D
# 题目
2407. 最长递增子序列 II - 力扣(LeetCode) (opens new window)
# 思路
前置题:300. 最长递增子序列 - 力扣(LeetCode) (opens new window)
# 1. DP + 线段树优化
前置题是一道 
而本题便是基于 
# 代码
class Solution {
public:
using ll = long long;
  std::vector<int> max;
  void modify(int u, int l, int r, int pos, int val) {
      if (l == r) max[u] = val;
      else {
          int mid = (l + r) >> 1;
          if (pos <= mid) modify(u << 1, l, mid, pos, val);
          else modify(u << 1 | 1, mid + 1, r, pos, val);
          max[u] = std::max(max[u << 1], max[u << 1 | 1]);
      }
  }
  int query(int u, int l, int r, int L, int R) {
      if (L <= l && r <= R) return max[u];
      int res = 0;
      int mid = (l + r) >> 1;
      if (L <= mid) res = query(u << 1, l, mid, L, R);
      if (R > mid) res = std::max(res, query(u << 1 | 1, mid + 1, r, L, R));
      return res;
  }
  int lengthOfLIS(vector<int>& nums, int k) {
      int n = nums.size();
      int mx = *max_element(nums.begin(), nums.end());
      max.resize(mx * 4 + 10);
      for (int i = 0; i < n; i ++) {
          if (nums[i] == 1) modify(1, 1, mx, 1, 1);
          else {
              int maxv = query(1, 1, mx, std::max(1, nums[i] - k), nums[i] - 1) + 1;
              modify(1, 1, mx, nums[i], std::max(1, maxv));
          }
      }
      return max[1];
  }
};
// Make sure to add code blocks to your code group
Last Updated: 3/4/2023, 5:38:14 PM
