力扣203周周赛题解
题目一:
示例
解题思路与代码实现
本题的思路为优化整个起点与终点,理清关系,起点到终点的过程中,分为起点小于终点,起点大于终点,起点等于终点,分为三种情况,中间重复的部分的次数都是相同的。注意起点大于终点的情况就可以了。具体见代码。简单的题型用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))
题目二:
示例
解题思路与代码实现
纯排序题,拍完序按照顺序进行取值即可
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;
}
};
题目三:
示例
解题思路与代码实现
注意理解题意,并进行分段处理即可,分为三种情况,插入之后新增一个段长为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];
}
}