-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
110 lines (94 loc) · 3.03 KB
/
main.go
File metadata and controls
110 lines (94 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Source: https://leetcode.com/problems/course-schedule-iii
// Title: Course Schedule III
// Difficulty: Hard
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// There are n different online courses numbered from 1 to n. You are given an array courses where courses[i] = [duration_i, lastDay_i] indicate that the ith course should be taken continuously for duration_i days and must be finished before or on lastDay_i.
//
// You will start on the 1st day and you cannot take two or more courses simultaneously.
//
// Return the maximum number of courses that you can take.
//
// Example 1:
//
// Input: courses = [[100,200],[200,1300],[1000,1250],[2000,3200]]
// Output: 3
// Explanation:
// There are totally 4 courses, but you can take 3 courses at most:
// First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day.
// Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day.
// Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day.
// The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date.
//
// Example 2:
//
// Input: courses = [[1,2]]
// Output: 1
//
// Example 3:
//
// Input: courses = [[3,2],[4,3]]
// Output: 0
//
// Constraints:
//
// 1 <= courses.length <= 10^4
// 1 <= duration_i, lastDay_i <= 10^4
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package main
import (
"container/heap"
"sort"
)
type intHeap []int
func (h intHeap) Len() int { return len(h) }
func (h intHeap) Less(i, j int) bool { return h[i] > h[j] } // max-heap
func (h intHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func newIntHeap(arr []int) *intHeap {
h := intHeap(arr)
heap.Init(&h)
return &h
}
func (h *intHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
func (h *intHeap) Pop() interface{} {
n := len(*h)
x := (*h)[n-1]
*h = (*h)[:n-1]
return x
}
func (h *intHeap) Peak() int {
if h.Len() == 0 {
return -1
}
return (*h)[0]
}
func scheduleCourse(courses [][]int) int {
// Sort by last day and duration
sort.Slice(courses, func(i, j int) bool {
return courses[i][1] < courses[j][1]
})
currDay := 0
takenCourses := newIntHeap(make([]int, 0, len(courses)))
for _, course := range courses {
duration := course[0]
lastDay := course[1]
// We can take this course
if currDay+duration <= lastDay {
currDay += duration
heap.Push(takenCourses, duration)
continue
}
// We don't have enough time. Try to replace a previous course with longest duration.
prev := takenCourses.Peak()
if prev > duration {
heap.Pop(takenCourses)
currDay += duration - prev
heap.Push(takenCourses, duration)
continue
}
}
return takenCourses.Len()
}