153th Weekly Contest
标签 : Leetcode Weekly Contest
5181.公交站间的距离
环形公交路线上有 n 个站,按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离,distance[i] 表示编号为 i 的车站和编号为 (i + 1) % n 的车站之间的距离。
环线上的公交车都可以按顺时针和逆时针的方向行驶。
返回乘客从出发点 start 到目的地 destination 之间的最短距离。
示例 1:
输入:distance = [1,2,3,4], start = 0, destination = 1
输出:1
解释:公交站 0 和 1 之间的距离是 1 或 9,最小值是 1。
示例 2:
输入:distance = [1,2,3,4], start = 0, destination = 2
输出:3
解释:公交站 0 和 2 之间的距离是 3 或 7,最小值是 3。
示例 3:
输入:distance = [1,2,3,4], start = 0, destination = 3
输出:4
解释:公交站 0 和 3 之间的距离是 6 或 4,最小值是 4。
提示:
- 1 <= n <= 10^4
- distance.length == n
- 0 <= start, destination < n
- 0 <= distance[i] <= 10^4
Solutions:
Answer 1:
// CopyRight By liouzhou_101
class Solution {
public:
int distanceBetweenBusStops(vector<int>& d, int start, int destination) {
int sum = 0;
int n = d.size();
for (int i = 0; i < n; ++ i) sum += d[i];
int ret = 0;
for (int i = start; i != destination; i = (i+1)%n) ret += d[i];
return min(ret, sum-ret);
}
};
Answer 2:
// CopyRight By darrenhp
class Solution {
public:
int distanceBetweenBusStops(vector<int>& distance, int start, int destination) {
vector<int> P(1);
partial_sum(distance.begin(), distance.end(), back_inserter(P));
if (start > destination) swap(start, destination);
int k = P[destination] - P[start];
return min(P.back() - k, k);
}
};
Answer 3:
// CopyRight By wnjxyk
class Solution {
public:
int distanceBetweenBusStops(vector<int>& distance, int start, int destination) {
int n=distance.size(), sum=0, forw=0;
for (int i=0; i<n; i++) sum+=distance[i];
while(start!=destination){
forw+=distance[start];
start=(start+1)%n;
}
return min(sum-forw, forw);
}
};
Answer 4:
// CopyRight By ghost-37
class Solution(object):
def distanceBetweenBusStops(self, distance, start, destination):
if start > destination:
start,destination = destination,start
sum_d = sum(distance)
cur_sum = 0
for i in range(start,destination):
cur_sum += distance[i]
return min(cur_sum,sum_d-cur_sum)
5183. 一周中的第几天
给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。
输入为三个整数:day、month 和 year,分别表示日、月、年。
您返回的结果必须是这几个值中的一个 {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}。
示例 1:
输入:day = 31, month = 8, year = 2019
输出:"Saturday"
示例 2:
输入:day = 18, month = 7, year = 1999
输出:"Sunday"
示例 3:
输入:day = 15, month = 8, year = 1993
输出:"Sunday"
提示:
给出的日期一定是在 1971 到 2100 年之间的有效日期。
Answer 1:class Solution: def dayOfTheWeek(self, day: int, month: int, year: int) -> str: import time import datetime #str 转 datetime string = str(year) + '-' + str(month) + '-' + str(day) date_time = datetime.datetime.strptime(string,'%Y-%m-%d') from datetime import datetime dayOfWeek = date_time.isoweekday() ###返回数字1-7代表周一到周日 dict = {1:"Monday", 2: "Tuesday", 3: "Wednesday", 4: "Thursday", 5: "Friday", 6: "Saturday", 7: "Sunday"} return dict[dayOfWeek]
Answer 2:
// CopyRight By darrenhp class Solution { public: bool isLeap(int y) { return y % 400 == 0 || (y % 100 != 0 && y % 4 == 0); } string dayOfTheWeek(int day, int month, int year) { vector<int> md = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; vector<string> ds = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; int tot = 3; for (int y = 1970; y < year; y++) { tot += isLeap(y)?366:365; } for (int m = 1; m < month; m++) { if (isLeap(year) && m == 2) tot += 29; else tot += md[m]; } tot += day; return ds[tot % 7]; } };
Answer 3:
class Solution { public: string ans[7]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; string dayOfTheWeek(int day, int month, int year) { if (month<3) { --year; month+=12; } int c=year/100, y=year%100; int w=(c/4-2*c+y+y/4+13*(month+1)/5+day-1)%7; return ans[(w+7)%7]; } };
Answer 4:
import java.util.*; class Solution { String b[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}; public String dayOfTheWeek(int day, int month, int year) { Calendar time = Calendar.getInstance(); time.set(year, month-1, day); int day1=time.get(Calendar.DAY_OF_WEEK); return b[day1-1]; } }
Answer 5:
from datetime import datetime class Solution(object): def dayOfTheWeek(self, day, month, year): ml = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"] x = datetime(year,month,day) return ml[x.weekday()]
5182. 删除一次得到子数组最大和
给你一个整数数组,返回它的某个 非空 子数组(连续元素)在执行一次可选的删除操作后,所能得到的最大元素总和。
换句话说,你可以从原数组中选出一个子数组,并可以决定要不要从中删除一个元素(只能删一次哦),(删除后)子数组中至少应当有一个元素,然后该子数组(剩下)的元素总和是所有子数组之中最大的。
注意,删除一个元素后,子数组 不能为空。
请看示例:
示例 1:
输入:arr = [1,-2,0,3]
输出:4
解释:我们可以选出 [1, -2, 0, 3],然后删掉 -2,这样得到 [1, 0, 3],和最大。
示例 2:
输入:arr = [1,-2,-2,3]
输出:3
解释:我们直接选出 [3],这就是最大和。
示例 3:
输入:arr = [-1,-1,-1,-1]
输出:-1
解释:最后得到的子数组不能为空,所以我们不能选择 [-1] 并从中删去 -1 来得到 0。我们应该直接选择 [-1],或者选择 [-1, -1] 再从中删去一个 -1。
提示:
- 1 <= arr.length <= 10^5
- -10^4 <= arr[i] <= 10^4
Answer 1:
// CopyRight By jfantasy
class Solution {
public:
int maximumSum(vector<int>& arr) {
const int n = arr.size();
vector<int> f(n, 0), g(n, 0);
for (int i = 0; i < n; ++i) {
f[i] = arr[i];
if (i > 0 && f[i - 1] > 0) f[i] += f[i - 1];
}
for (int i = n - 1; i >= 0; --i) {
g[i] = arr[i];
if (i < n - 1 && g[i + 1] > 0) g[i] += g[i + 1];
}
int ans = f[0];
for (int i = 0; i < n; ++i) {
ans = max(ans, max(f[i], g[i]));
if (i + 1 < n) ans = max(ans, f[i] + g[i + 1]);
if (i + 2 < n) ans = max(ans, f[i] + g[i + 2]);
}
return ans;
}
};
Answer 2:
class Solution {
public:
int maximumSum(vector<int>& arr) {
int l = arr.size(), ans = -2e9;
vector<int> f(l);
for (int i = 0, sum = 0; i < l; ++i) {
sum = max(sum + arr[i], arr[i]);
f[i] = sum;
}
for (int i = l - 1, sum = 0; i >= 0; --i) {
sum = max(sum + arr[i], arr[i]);
ans = max(ans, max<int>(sum, i - 2 >= 0 ? sum + f[i - 2] : -2e9));
}
return ans;
}
};
Answer 3:
class Solution(object):
def maximumSum(self, arr):
import numpy as np
n = len(arr)
if ( n == 1 ):
return arr[0]
if (max(arr) < 0):
return max(arr)
left = np.zeros((n,),dtype=np.int32)
right = np.zeros((n,),dtype=np.int32)
left[0] = max(0,arr[0])
for i in range(1,n):
left[i] = max(0,left[i-1]+arr[i])
right[n-1] = max(0,arr[n-1])
for i in range(n-2,-1,-1):
right[i] = max(0,right[i+1]+arr[i])
ans = 0
for i in range(1,n-1):
ans = max(ans,left[i-1]+right[i+1]+max(0,arr[i]))
ans = max(ans,right[1]+max(0,arr[0]))
ans = max(ans,left[n-2]+max(0,arr[n-1]))
return ans
5184. 使数组严格递增
给你两个整数数组 arr1 和 arr2,返回使 arr1 严格递增所需要的最小「操作」数(可能为 0)。
每一步「操作」中,你可以分别从 arr1 和 arr2 中各选出一个索引,分别为 i 和 j,0 <= i < arr1.length 和 0 <= j < arr2.length,然后进行赋值运算 arr1[i] = arr2[j]。
如果无法让 arr1 严格递增,请返回 -1。
示例 1:
输入:arr1 = [1,5,3,6,7], arr2 = [1,3,2,4]
输出:1
解释:用 2 来替换 5,之后 arr1 = [1, 2, 3, 6, 7]。
示例 2:
输入:arr1 = [1,5,3,6,7], arr2 = [4,3,1]
输出:2
解释:用 3 来替换 5,然后用 4 来替换 3,得到 arr1 = [1, 3, 4, 6, 7]。
示例 3:
输入:arr1 = [1,5,3,6,7], arr2 = [1,6,3,3]
输出:-1
解释:无法使 arr1 严格递增。
提示:
- 1 <= arr1.length, arr2.length <= 2000
- 0 <= arr1[i], arr2[i] <= 10^9
Answer 1:
// CopyRight By wnjxyk
int pool[2050];
int dp[2050][2050];
class Solution {
public:
int makeArrayIncreasing(vector<int>& arr1, vector<int>& arr2) {
int n=arr1.size(), m=arr2.size();
for (int i=0; i<m; i++) pool[i]=arr2[i];
sort(pool, pool+m);
m=unique(pool, pool+m)-pool;
memset(dp, -1, sizeof(dp));
dp[0][m]=0; for (int i=0; i<m; i++) dp[0][i]=1;
for (int i=0; i<n-1; i++){
for (int j=0; j<=m; j++){
if (dp[i][j]==-1) continue;
int now_v=(j==m?arr1[i]:pool[j]);
// Don't
if (arr1[i+1]>now_v){
if (dp[i+1][m]==-1 || dp[i+1][m]>dp[i][j]) dp[i+1][m]=dp[i][j];
}
// Modify
int nxt_p=upper_bound(pool, pool+m, now_v)-pool;
if (nxt_p<m){
// printf("Change(%d) %d->%d\n", i, arr1[i], pool[nxt_p]);
if (dp[i+1][nxt_p]==-1 || dp[i+1][nxt_p]>dp[i][j]+1) dp[i+1][nxt_p]=dp[i][j]+1;
}
}
}
int ans=-1;
for (int i=0; i<=m; i++){
if (dp[n-1][i]==-1) continue;
if (ans==-1 || ans>dp[n-1][i]) ans=dp[n-1][i];
}
return ans;
}
};
Answer 2:
# ghost-37
class Solution(object):
def makeArrayIncreasing(self, arr1, arr2):
import bisect
n1 = len(arr1)
n2 = len(arr2)
arr2 = sorted(arr2)
dp = [{} for i in range(n1)]
if min(arr2) < arr1[0]:
dp[0][min(arr2)] = 1
dp[0][arr1[0]] = 0
for i in range(1,n1):
for k,v in dp[i-1].items():
if arr1[i] > k:
if not arr1[i] in dp[i]:
dp[i][arr1[i]] = 10000
dp[i][arr1[i]] = min(dp[i][arr1[i]],v)
nv = bisect.bisect_right(arr2,k)
if nv == n2: continue
nv = arr2[nv]
if not nv in dp[i]:
dp[i][nv] = 10000
dp[i][nv] = min(dp[i][nv],v+1)
ans = 10000
for k,v in dp[n1-1].items():
ans = min(ans,v)
if ans >= 10000: ans = -1
return ans