LeetCode 第 153 场周赛 【公交站间的距离】【一周中的第几天】【删除一次得到子数组最大和】

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;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值