力扣(leetcode)第 203 场周赛 题解

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

题目比较长,要认真读题。读懂后,不难发现其实只要求出开始位置和结束位置上所有的点就可以了,因为他们之间的点一定是走过最多的。
注意:起始位置可能不是1。

class Solution {
public:
    vector<int> mostVisited(int n, vector<int>& rounds) {
        vector<int> ans;
        int l=rounds[0];
        int r=rounds[rounds.size()-1];
        while(1)
        {
            ans.push_back(l);
            if(l==r)break;
            l=l%n+1;
        }
        sort(ans.begin(),ans.end());
        return ans;
    }
};

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

由于每次都拿不到最大的,那么就每次拿第二大的就可以了,排序后遍历,然后记录下一共拿了多少个,拿完了就退出。

class Solution {
public:
    int maxCoins(vector<int>& piles) {
        int ans=0,cnt=0;
        sort(piles.begin(),piles.end());
        for(int i=piles.size()-2;i>=0;i-=2)
        {
            ans+=piles[i];
            cnt++;
            if(cnt==piles.size()/3)break;
        }
        return ans;
    }
};

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

对于连续的一段 1 1 1,我们只需要知道它的起点和终点就可以了,那么我们用数组 a [ i ] a[i] a[i]表示以第 i i i个位置为结尾的 1 1 1的长度是多少,数组 b [ i ] b[i] b[i]表示以第 i i i个位置为起点的 1 1 1的长度是多少。接下来我们循环遍历 a r r arr arr,那么对于当前点 a r r [ i ] arr[i] arr[i]来说,通过加入这个 1 1 1连接两边形成的新的连续 1 1 1的长度就是 a [ a r r [ i ] − 1 ] + b [ a r r [ i ] + 1 ] + 1 a[arr[i]-1]+b[arr[i]+1]+1 a[arr[i]1]+b[arr[i]+1]+1,这时再更新这个新的"连续1"的起点和终点的 a , b a,b a,b。但是这个题目问的是能否还有长度为 m m m的连续1,我们再开一个变量记录当前有几个长度为 m m m的连续1,循环中更新就可以了。

class Solution {
public:
    int findLatestStep(vector<int>& arr, int m) {
        int a[100005],b[100005],cnt=0;
        memset(a,0,sizeof(a));//houzui
        memset(b,0,sizeof(b));//qianzui
        int ans=-1;
        for(int i=0;i<arr.size();i++)
        {
            int c=a[arr[i]-1]+b[arr[i]+1]+1;
            if(c==m)cnt++;
            if(a[arr[i]-1]==m)cnt--;//原来的m个1消失了
            if(b[arr[i]+1]==m)cnt--;//原来的m个1消失了
            if(cnt)ans=i+1;
            a[arr[i]+b[arr[i]+1]]=c;
            b[arr[i]-a[arr[i]-1]]=c;
        }
        return ans;
    }
};

D.石子游戏 V

DP,对于每一段区间 l , r l,r l,r,枚举中间分界点,取最大的结果即可,预处理前缀和来加速计算。

class Solution {
    int sum[505];
    int dp[505][505];
    int dfs(int l,int r)
    {
        if(dp[l][r])
            return dp[l][r];
        for(int i=l;i<=r;i++)
        {
            int s=0;
            int ll=sum[i]-sum[l-1];
            int rr=sum[r]-sum[i];
            if(ll>rr)
                s=rr+dfs(i+1,r);
            else if(ll<rr)
                s=ll+dfs(l,i);
            else
                s=ll+max(dfs(i+1,r),dfs(l,i));
            dp[l][r]=max(dp[l][r],s);
        }
        return dp[l][r];
    }
public:
    int stoneGameV(vector<int>& stoneValue) {
        for(int i=0;i<stoneValue.size();i++)
            sum[i+1]=sum[i]+stoneValue[i];
        return dfs(1,stoneValue.size());
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值