1. 程式人生 > >課程排程問題:LeetCode 630. Course Schedule III

課程排程問題:LeetCode 630. Course Schedule III

題目描述:
There are n different online courses numbered from 1 to n. Each course has some duration(course length) t and closed on dth day. A course should be taken continuously for t days and must be finished before or on the dth day. You will start at the 1st day.

Given n online courses represented by pairs (t,d), your task is to find the maximal number of courses that can be taken.
示例:


Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]]
Output: 3

解題思路:

  1. 將課程按due time排序,due time排序在前的表示優先順序較高,需要先完成;
  2. 遍歷排序後的課程,若某個課程可在due time前結束,則將該課程的耗費時間加入排程list中,並更新已花費的時間consumingTIme的值;
  3. 若某個課程不可在due time前結束,則首先判斷該課程耗費時間是否比list中最長的耗費時間還要長,若是,則不新增該課程;若不是,則刪除list中最長的耗費時間並將該時間加入list中。

原理:

  • 按due time排序可保證所有課程較好的時間順序加入list; 若出現某個課程A的due time較小,但consuming time較長的課程,該課程會慢慢被後續consuming time較短的課程B替換掉;
  • 且因為B的due time(d1)都比A的due time (d2)大,B的consuming time(c1)都比A的consuming time(c2)小;
  • 且A在list中,所以當前時間+c2 < d2,那麼當前時間+c1< d1肯定成立。所以B肯定可以替換A,且可以使得當前時間變小。所以這是一個最優策略。

原始碼

class Solution(object):
    def scheduleCourse(self, courses):
        #用於查詢list中的元素//二分查詢
        def findElement(l, s, e, x):
            if
s > e: return s mid = int((s + e) / 2) if l[mid] < x: if mid == len(l) - 1: return mid + 1 if l[mid + 1] >= x: return mid + 1 return findElement(l, mid + 1, e, x) if l[mid] > x: if mid == 0: return 0 if l[mid - 1] <= x: return mid return findElement(l, s, mid - 1, x) return mid if courses == []: return 0 #按照結束時間排序 courses.sort(key = lambda x : x[1]) res = [courses[0][0]] #已花去的時間 consumingTimes = res[0] for i in courses[1:]: #若課程可在due time前完成,則直接加入list if consumingTimes + i[0] <= i[1]: pos = findElement(res, 0, len(res) - 1, i[0]) if pos == len(res): res.append(i[0]) else: res.insert(pos, i[0]) consumingTimes += i[0] #否則若該課程耗費時間較少,則替換list中耗費時間最長的課程 else: if i[0] < res[-1]: consumingTimes += i[0] - res[-1] del res[-1] pos = findElement(res, 0, len(res) - 1, i[0]) if pos == len(res): res.append(i[0]) else: res.insert(pos, i[0]) return len(res)