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
思路:乘客从出发点A到目的地B的走法有两种情况
(1)A顺时针走向B
(2)A逆时针走向B(距离等同于B顺时针走向A)
所有比较两种情况取最小
public int distanceBetweenBusStops(int[] distance, int start, int destination) {
int len = distance.length;
if (start == destination) return 0;
int rightIndex = (start + 1) % len;
int min = Integer.MAX_VALUE;
int sum = distance[start];
while (rightIndex != destination) {
sum += distance[rightIndex];
rightIndex = (rightIndex + 1) % len;
}
min = Math.min(min, sum);
rightIndex = (destination + 1) % len;
sum = distance[destination];
while (rightIndex != start) {
sum += distance[rightIndex];
rightIndex = (rightIndex + 1) % len;
}
min = Math.min(min, sum);
return min;
}
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 年之间的有效日期。
代码:
public String dayOfTheWeek(int day, int month, int year) {
String[] res = {"Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday"};
String old = "1971-01-01";
String now = "" + year + "-" + month + "-" + day;
int sum = 0;
for (int start = 1971; start != year; start++) {
if((start % 4 == 0 && start % 100 != 0) || (start % 400 == 0)){
sum += 366;
} else {
sum += 365;
}
}
sum += dayOfYear(now);
sum = sum % 7;
return res[sum];
}
public int dayOfYear(String date) {
String[] str = date.split("-");
int[] data = new int[str.length];
for (int i = 0; i < str.length; i++) {
data[i] = Integer.valueOf(str[i]);
}
int sum=0;
int Mon=data[1];
int Year=data[0];
int Day=data[2];
switch(Mon){
case 12:sum += 30;
case 11:sum += 31;
case 10:sum += 30;
case 9 :sum += 31;
case 8 :sum += 31;
case 7 :sum += 30;
case 6 :sum += 31;
case 5 :sum += 30;
case 4 :sum += 31;
case 3 :
if((Year % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0)){
sum += 29;
}
else{
sum += 28;
}
case 2 :sum += 31;
case 1 :sum += Day;
}
return sum;
}
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
思路:使用left和right辅助数组
- 找到不删除第i个位置时以i位置结尾的子数组最大和,记录在left数组
- 找到不删除第i个位置时以i位置开始的子数组最大和,记录在right数组
- 然后遍历辅助数组,删除第i个位置,然后判断以i-1位置结尾和以i+1位置开始的数组最大和(相当于连接两个子数组成为一个子数组)
代码:
public static int maximumSum(int[] arr) {
int n = arr.length;
int[] left = new int[n];
int[] right = new int[n];
int temp = arr[0], max = arr[0];
left[0] = arr[0];
// 找到不删除第i个位置时以i位置结尾的子数组最大和,记录在left数组
for (int i = 1; i < n; i++) {
temp = Math.max(arr[i], temp + arr[i]);
max = Math.max(max, temp);
left[i] = temp;
}
temp = right[n-1] = arr[n-1];
// 找到不删除第i个位置时以i位置开始的子数组最大和,记录在right数组
for (int i = n - 2; i >= 0; i--) {
temp = Math.max(arr[i], temp + arr[i]);
right[i] = temp;
}
int res = max;
// 删除第i个位置,然后判断以i-1位置结尾和以i+1位置开始的数组最大和(相当于连接两个子数组成为一个子数组)
for (int i = 1; i < n - 1; i++){
res = Math.max(res, left[i-1] + right[i+1]);
}
return res;
}