目录
T1. 5495. 圆形赛道上经过次数最多的扇区
这一题直接暴力模拟即可,注意圆环有一个开闭区间的问题,还有最后的一个数会没有被计数上,要单独判断
class Solution {
public:
vector<int> mostVisited(int n, vector<int>& rounds) {
vector<int> ans;
// 表示区间内每个数被计数的次数
vector<int> temp(n+1,0);
// 开闭区间问题, 选择左闭右开区间
for (int i = 0; i<rounds.size() - 1; i++) {
if (rounds[i] <= rounds[i+1]) {
for (int j = rounds[i]; j<rounds[i+1]; j++) {
temp[j]++;
}
} else {
for (int j = rounds[i]; j<=n; j++) {
temp[j]++;
}
for (int j = 1; j<rounds[i+1]; j++) {
temp[j]++;
}
}
}
// 最后一个是少计数一次,所以要额外加上
temp[rounds[rounds.size()-1]]++;
// 找出最大被计数的次数
int maxnum = temp[1];
for (int i = 1; i<temp.size(); i++) {
maxnum = max(maxnum, temp[i]);
}
// 防止有多个最大值的情况发生,将其所有的计入
for (int i = 1; i<temp.size(); i++) {
if (temp[i] == maxnum)
ans.push_back(i);
}
return ans;
}
};
T2. 5496. 你可以获得的最大硬币数目
这一题先排序,然后找出每隔两个找出需要获得的硬币数量相加,贪心的思想
class Solution {
public:
int maxCoins(vector<int>& piles) {
sort(piles.begin(), piles.end());
int ans = 0;
if (piles.size() == 3)
return piles[1];
for (int i = piles.size()-2; i>piles.size()/3-1; i-=2) {
ans += piles[i];
}
return ans;
}
};
T3. 5497. 查找大小为 M 的最新分组
这题找长度恰好为1的子数组其实可以借鉴一下这一题的思想:
class Solution {
public:
int findLatestStep(vector<int>& arr, int m) {
int n = arr.size();
if (n == m) return n;
map<int,int> mp;
mp[0] = n;
for (int i = n - 1; i >= 0; --i) {
int x = arr[i] - 1;
auto it = prev(mp.upper_bound(x));
int l = it->first, r = it->second;
if (l < x) {
if (x - l == m) return i;
mp[l] = x;
}
if (r > x + 1) {
if (r - x - 1 == m) return i;
mp[x + 1] = r;
}
}
return -1;
}
};
T4. 5498. 石子游戏 V
石子问题没有搞过,看大佬的题解吧。。。经典的DP问题啊
class Solution {
public int stoneGameV(int[] stoneValue) {
int n = stoneValue.length;
int[] sum = new int[n];
sum[0] = stoneValue[0];
for (int i = 1; i < n; i++) {
sum[i] = sum[i - 1] + stoneValue[i];
}
int[][] dp = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j + i < n; j++) {
int left = j;
int right = j + i;
int max = 0;
for (int mid = left; mid < right; mid++) {
int sumleft = getsum(sum, left, mid);
int sumright = getsum(sum, mid + 1, right);
if (sumleft < sumright) {
max = Math.max(max, sumleft + dp[left][mid]);
} else if (sumleft > sumright) {
max = Math.max(max, sumright + dp[mid + 1][right]);
} else {
max = Math.max(max, sumleft + dp[left][mid]);
max = Math.max(max, sumright + dp[mid + 1][right]);
}
}
dp[left][right] = max;
}
}
return dp[0][n - 1];
}
public int getsum(int[] sum, int left, int right) {
if (left == 0) {
return sum[right];
}
return sum[right] - sum[left - 1];
}
}