【每日一题】Day0004:力扣题库NO.630. 课程表 III

小白首次挑战困难难度的题目,有些紧张。有大体思路,不过实现过程中不断发现小问题进行修正,最终终于实现(虽然效率很低。)

惯例题目链接如下:

力扣icon-default.png?t=LA92https://leetcode-cn.com/problems/course-schedule-iii/拿到题目其实很快就有大概的思路,以人脑解决办法正面解决,用代码实现:

1. 将二维数组按lastDayi从小到大,将courses排序。因为解决类似问题的时候,我们总是优先将死线更近的任务完成。

2. 顺序去修课,当一门课修完会超过其截至日期时,看看这门课的耗时长短。如果其耗时比之前的任何一门课耗时都长,那这门课直接不修;否则就把之前耗时最长的课取消不修,然后从当前下标开始继续尝试。当最终数组遍历后应该就能得到我们能够修的课程数量了。

代码如下:

package cn.daycode.leetcode;

import java.util.Arrays;
import java.util.Comparator;

public class ScheduleCourse {
    public static void main(String[] args) {
        int[][] courses = {{5316,5539},{1968,5258},{6008,6376},{4025,5081},{9422,9652},{1300,7475},{3438,5926},{4334,7554},
                {2454,2481},{1382,7434},{4280,7787},{2834,3481},{4439,5925},{3848,9651},{5682,5927},{2745,8029},{3898,7332},
                {1744,8260},{3895,7675},{5257,6836},{5586,7090},{2212,7901},{6040,9640},{666,9693},{4763,5795},{2132,7532},
                {3076,9298},{1667,1733},{7058,9231},{7999,8981},{2199,7501},{7269,9281},{1406,3057},{2382,2685},{1107,5729},
                {1357,2141},{2277,3607},{821,2855},{845,7927},{2279,3773},{6072,8149},{797,5610},{194,5662},{2262,6519},
                {2951,8657},{2357,9152},{3400,6883},{6214,7857},{380,474},{70,7662},{3027,8212},{1061,9351},{376,6165},
                {5774,8474},{6917,9587},{2191,6224},{2925,5461},{2174,9707},{5475,8085},{6760,7256},{1961,6300},{9000,9501},
                {4116,7913},{7557,9883},{1502,8031},{194,5219},{6651,9651},{4834,9967},{3829,7982},{6087,8932},{4905,5405},
                {3415,8174},{211,9092},{3905,7749},{496,7582},{2330,7303},{2747,6366},{5387,7599},{3838,9834},{4497,8327},
                {1005,4160},{219,6149},{1946,5510},{1892,6955},{4461,7448},{3066,4207},{5499,8181},{301,5991},{7200,8207},
                {5025,8044},{419,5976},{1799,3661},{783,3457},{3319,7522},{21,9533},{2772,9705},{542,9356},{8025,8492},
                {3626,5314},{3521,7776},{6825,7465},{2744,8611},{2185,9147},{5934,8083},{2844,7382},{3670,5455},{6068,8561},
                {9577,9697},{434,5921},{6273,9638},{4714,6038},{2744,7207},{2903,3155},{2027,5216},{2838,2987},{4458,7430},
                {1693,6371},{6168,8734},{6785,8121},{5589,6785},{846,9311},{1061,7134},{1906,4968},{2870,5697},{4438,7383},
                {2342,4661},{543,2039},{3478,8099},{6842,8123},{2725,9033},{3723,5698},{22,7944},{7752,8346},{3956,8991},
                {2357,7846},{4030,7664},{7708,9249},{8605,9059},{3955,6844},{4343,4483},{1863,4776},{5764,9974},{619,4251},
                {4226,9907},{45,5876},{2334,9871},{2087,8635},{4826,8934},{346,3530},{3714,5776},{9197,9989},{7625,9490}};

        System.out.println(scheduleCourse(courses));

    }

    public static int scheduleCourse(int[][] courses) {
        int[][] temp = new int[courses.length][2];
        System.arraycopy(courses,0,temp,0,courses.length);
        int count = 0; // 记录修的门数
        int day = 0; // 记录已经耗的天数
        int flag = 0; // flag用来记录寻找到目前位置学时最长的科目,下标从0开始

        sortCourses(temp);

        for (int i = 0; i < temp.length; i++) {
            if(day + temp[i][0] <= temp[i][1]){ // 如果修完累计天数day没到截止天数就正常计算
                if(temp[i][0] > temp[flag][0]){ // 临时记录一下截至i位置,学时最长的科目下标
                    flag = i;
                }
                count++; // 记录修的门数
                day = day + temp[i][0];  // 记录到目前为止已经花费的天数
            }else{ // 否则就尝试将后面的课替换掉前面的课程
                if(temp[i][0] < temp[flag][0]){ // 如果无法修完,判断一下是否比之前最长的短,如果是去掉之前耗时最长的课程
                    count--;
                    day = day - temp[flag][0];
                    temp[flag][0] = 0; // 原本的最大值赋0防止被再次找到
                    flag = findMax(temp, --i); // 找到已修过课程中最耗时的课程记录下标
                }else{
                    temp[i][0] = 0; // 如果当前课程比之前耗时最长的课程还长则略过,赋0
                }
            }
        }

        return count;
    }

    // 找到temp二维数组中下标0到i-1中temp[j][0]的最大值并返回下标j
    private static int findMax(int[][] temp, int i) {
        int flag = 0;

        for(int j=0; j < i;j++){
            if(temp[flag][0] < temp[j][0]){
                flag = j;
            }
        }

        return flag;
    }

    // 把courses二维数组按照lastDay从小到大排序
    public static void sortCourses(int[][] courses){
        Arrays.sort(courses, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                if (o1[1]==o2[1]) return o1[0]-o2[0];
                return o1[1]-o2[1];
            }
        });
    }
}

错误提交没通过的测试用例,我截取了一小部分没删。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值