LeetCode美团专场——第203场周赛题解

目录

T1. 5495. 圆形赛道上经过次数最多的扇区

T2. 5496. 你可以获得的最大硬币数目

 T3. 5497. 查找大小为 M 的最新分组

T4. 5498. 石子游戏 V


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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉迷单车的追风少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值