[Swift]LeetCode855. 考場就座 | Exam Room

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: http://www.javashuo.com/article/p-dklvcyjc-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

In an exam room, there are N seats in a single row, numbered 0, 1, 2, ..., N-1.git

When a student enters the room, they must sit in the seat that maximizes the distance to the closest person.  If there are multiple such seats, they sit in the seat with the lowest number.  (Also, if no one is in the room, then the student sits at seat number 0.)github

Return a class ExamRoom(int N) that exposes two functions: ExamRoom.seat() returning an int representing what seat the student sat in, and ExamRoom.leave(int p) representing that the student in seat number p now leaves the room.  It is guaranteed that any calls to ExamRoom.leave(p) have a student sitting in seat p微信

Example 1:app

Input: ["ExamRoom","seat","seat","seat","seat","leave","seat"], [[10],[],[],[],[],[4],[]] Output: [null,0,9,4,2,null,5] Explanation: ExamRoom(10) -> null seat() -> 0, no one is in the room, then the student sits at seat number 0. seat() -> 9, the student sits at the last seat number 9. seat() -> 4, the student sits at the last seat number 4. seat() -> 2, the student sits at the last seat number 2. leave(4) -> null seat() -> 5, the student sits at the last seat number 5.​​​​​​​

Note:函數

  1. 1 <= N <= 10^9
  2. ExamRoom.seat() and ExamRoom.leave() will be called at most 10^4 times across all test cases.
  3. Calls to ExamRoom.leave(p) are guaranteed to have a student currently sitting in seat number p.

在考場裏,一排有 N 個座位,分別編號爲 0, 1, 2, ..., N-1 。測試

當學生進入考場後,他必須坐在可以使他與離他最近的人之間的距離達到最大化的座位上。若是有多個這樣的座位,他會坐在編號最小的座位上。(另外,若是考場裏沒有人,那麼學生就坐在 0 號座位上。)spa

返回 ExamRoom(int N) 類,它有兩個公開的函數:其中,函數 ExamRoom.seat() 會返回一個 int (整型數據),表明學生坐的位置;函數 ExamRoom.leave(int p) 表明坐在座位 p上的學生如今離開了考場。請確保每次調用 ExamRoom.leave(p) 時都有學生坐在座位 p 上。 code

示例:htm

輸入:["ExamRoom","seat","seat","seat","seat","leave","seat"], [[10],[],[],[],[],[4],[]]
輸出:[null,0,9,4,2,null,5]
解釋:
ExamRoom(10) -> null
seat() -> 0,沒有人在考場裏,那麼學生坐在 0 號座位上。
seat() -> 9,學生最後坐在 9 號座位上。
seat() -> 4,學生最後坐在 4 號座位上。
seat() -> 2,學生最後坐在 2 號座位上。
leave(4) -> null
seat() -> 5,學生最後坐在 5 號座位上。 

提示:

  1. 1 <= N <= 10^9
  2. 在全部的測試樣例中 ExamRoom.seat() 和 ExamRoom.leave() 最多被調用 10^4 次。
  3. 調用 ExamRoom.leave(p) 時須要確保當前有學生坐在座位 p 上。

336ms

 1 class ExamRoom {    
 2     var students: [Int]
 3     let N: Int
 4 
 5     init(_ N: Int) {
 6         students = [Int]()
 7         self.N = N
 8     }
 9     
10     // with sort it's O(PlogP), with index it's O(P)
11     func seat() -> Int {
12         var student = 0
13         var index = 0
14         if students.count > 0 {
15             var prev: Int? = nil
16             var dist = students.first ?? 0
17             for (i, studentPos) in students.enumerated() {
18                 if let prev = prev {
19                     let d: Int = (studentPos - prev) / 2
20                     if d > dist {
21                         dist = d
22                         student = prev + d
23                         index = i
24                     }
25                 }
26                 prev = studentPos
27             }
28             if N - 1 - (students.last ?? 0) > dist {
29                 student = N - 1
30                 index = students.count
31             }
32         }
33         students.insert(student, at: index)
34         return student
35     }
36     
37     // O(P), because of remove.
38     func leave(_ p: Int) {
39         for i in 0..<students.count {
40             if students[i] == p {
41                 students.remove(at: i)
42                 return
43             }
44         }
45     }
46 }
47 
48 // wrong
49 class ExamRoom1 {
50     
51     var seats: [Bool]
52 
53     init(_ N: Int) {
54         seats = Array(repeating: false, count: N)
55     }
56     
57     func seat() -> Int {
58         let index = findSeat(0, seats.count - 1)
59         seats[index] = true
60         return index
61     }
62     
63     func leave(_ p: Int) {
64         seats[p] = false
65     }
66     
67     private func findSeat(_ l: Int, _ r: Int) -> Int {
68         if seats[l] == false {
69             return 0
70         }
71         if seats[r] == false {
72             return r
73         }
74         let m = (l + r) / 2
75         if seats[m] == false {
76             return m
77         }
78         let lh = findSeat(l, m)  
79         if seats[lh] == false {
80             return lh
81         }
82         
83         let rh = findSeat(m, r)
84         if seats[rh] == false {
85             return rh
86         }
87         return -1
88     }
89 }
90 
91 /**
92  * Your ExamRoom object will be instantiated and called as such:
93  * let obj = ExamRoom(N)
94  * let ret_1: Int = obj.seat()
95  * obj.leave(p)
96  */ 

Runtime: 2084 ms
Memory Usage: 20.1 MB
 1 class ExamRoom {
 2     static var N:Int = 0
 3     var pq:[Interval] = [Interval]()
 4 
 5     init(_ N: Int) {
 6         ExamRoom.N = N
 7         pq.append(Interval(-1, N))       
 8     }
 9     
10     func seat() -> Int {
11         var seat:Int = 0
12         var interval:Interval = pq.removeFirst()
13         if interval.x == -1 {seat = 0}
14         else if interval.y == ExamRoom.N {seat = ExamRoom.N - 1}
15         else {seat = (interval.x + interval.y) / 2}
16         offer(Interval(interval.x, seat))
17         offer(Interval(seat, interval.y))
18         return seat      
19     }
20     
21     func leave(_ p: Int) {
22         var head:Interval? = nil
23         var tail:Interval? = nil
24         for interval in pq
25         {
26             if interval.x == p {tail = interval}
27             if interval.y == p {head = interval}
28             if head != nil && tail != nil {break}
29         }
30         removeEle(head!)
31         removeEle(tail!)
32         offer(Interval(head!.x, tail!.y))
33     }
34     
35     func removeEle(_ interval:Interval)
36     {
37         for i in (0..<pq.count).reversed()
38         {
39             if pq[i].x == interval.x && pq[i].y == interval.y && pq[i].dist == interval.dist
40             {
41                 pq.remove(at:i)
42             }
43         }
44     }
45 
46     func offer(_ interval:Interval)
47     {
48         pq.append(interval)
49         pq.sort(by:{(a:Interval,b:Interval) -> Bool in 
50                 if a.dist == b.dist
51                 {
52                     return a.x <= b.x
53                 }
54                 else
55                 {
56                     return a.dist > b.dist
57                 }
58         })
59     }
60 }
61 
62 class Interval{
63     var x:Int
64     var y:Int
65     var dist:Int
66     init(_ x:Int,_ y:Int)
67     {
68         self.x = x
69         self.y = y
70         if x == -1
71         {
72             self.dist = y
73         }
74         else if y == ExamRoom.N
75         {
76             self.dist = ExamRoom.N - 1 - x
77         }
78         else
79         {
80             self.dist = abs(x - y) / 2
81         }
82     }
83 }
84 
85 /**
86  * Your ExamRoom object will be instantiated and called as such:
87  * let obj = ExamRoom(N)
88  * let ret_1: Int = obj.seat()
89  * obj.leave(p)
90  */ 
相關文章
相關標籤/搜索