20200907:力扣203周周赛题解记录

力扣203周周赛题解

题目一:

1.圆形赛道上经过次数最多的扇区
在这里插入图片描述

示例

在这里插入图片描述

解题思路与代码实现

本题的思路为优化整个起点与终点,理清关系,起点到终点的过程中,分为起点小于终点,起点大于终点,起点等于终点,分为三种情况,中间重复的部分的次数都是相同的。注意起点大于终点的情况就可以了。具体见代码。简单的题型用python更加简单,复杂的题型用Java和cpp更加清晰易懂。

class Solution:
    def mostVisited(self, n: int, rounds: List[int]) -> List[int]:
        start,end = rounds[0],rounds[-1]
        # 三种情况依次来写即可
        if start < end :
            return list(range(start,end+1));
        elif start == end :
            return list(range(start,start+1))
        else :
            return list(range(1,end+1)) + list(range(start,n+1))

题目二:

2.你可以获得的最大硬币数目
在这里插入图片描述

示例

在这里插入图片描述

解题思路与代码实现

纯排序题,拍完序按照顺序进行取值即可

python实现:

class Solution:
    def maxCoins(self, piles: List[int]) -> int:
        # python提供的更加简洁的表达格式,注意与matlab中区间及给定步长使用的区分
        return sum(sorted(piles)[len(piles) // 3::2])

不太熟悉python的同学看cpp代码实现:

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

题目三:

3.查找大小为 M 的最新分组
在这里插入图片描述

示例

在这里插入图片描述

解题思路与代码实现

注意理解题意,并进行分段处理即可,分为三种情况,插入之后新增一个段长为1的段,或者原有段长数量减一,原有段长加一段增加一,或者原有两个段减一,新增一个大段。分类来写即可。

class Solution {
    
    
    public int findLatestStep(int[] arr, int m) {
    
    
        int[] link = new int[arr.length + 2];
        int cnt = 0;
        int res = -1;

        for (int i = 0; i < arr.length; i++) {
    
    

            int x = arr[i];
           
            int l = link[x - 1] != 0 ? link[x - 1] : x;
           
            int r = link[x + 1] != 0 ? link[x + 1] : x;
            
           
            if (x - l == m) {
    
    
                cnt--;
            }
            if (r - x == m) {
    
    
                cnt--;
            }
            if (r - l + 1 == m) {
    
    
                cnt++;
            }
            if (cnt > 0) {
    
    
                res = i + 1;
            }

            
            link[l] = r;
            link[r] = l;
        }
        return res;
    }
}

题目四:

4.石子游戏 V

在这里插入图片描述

示例

在这里插入图片描述

解题思路与代码实现

前缀和以及动态规划的进阶题目,石子游戏的前面几道题理解到位的话本题应该问题不大,注意状态转移方程的给定。

class Solution {
    
    
    public int stoneGameV(int[] stoneValue) {
    
    
        int N = stoneValue.length;
        int[][] dp = new int[N][N];
        
        // 前缀和优化
        int[] preSum= new int[N];
        preSum[0]=stoneValue[0];
        for (int i = 1; i < stoneValue.length; i++) {
    
    
            preSum[i] =preSum[i-1]+stoneValue[i];
        }
        
        // dp即可
        for (int len = 2; len <=N ; len++) {
    
    
            for (int i = 0; i+len-1 <N ; i++) {
    
    
                int j = i+len-1;
                for (int m = i; m <=j ; m++) {
    
    
                    if (i>m || m+1>j){
    
    
                        continue;
                    }
                    int l = dp[i][m];   
                    int r = dp[m+1][j]; 
                    int ls =  preSum[m] - (i>0? preSum[i-1]:0); // i ~ m 分数
                    int rs = preSum[j]- preSum[m]; //m+1 ~ j 分数
                    
                    //左右区间分数相同,取大的
                    if (ls == rs){
    
    
                        int score = Math.max(l,r)+ls;
                        dp[i][j] = Math.max(dp[i][j],score);
                    }
                    // 左右不等,取小的
                    else{
    
    
                        if (ls>rs){
    
    
                            dp[i][j] = Math.max(dp[i][j],r+rs);
                        }else{
    
    
                            dp[i][j] = Math.max(dp[i][j],l+ls);
                        }
                    }
                }
            }

        }
        return dp[0][N-1];
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36828395/article/details/108460000