###### Agenda: ###### 12/13 22:00(UTC+8) 12/13 07:00(UTC-7) ###### 公布這次live session題目 ###### 12/13 22:30(UTC+8) 12/13 07:30(UTC-7) ###### 開始逐步給hint ###### 12/13 23:00(UTC+8) 12/13 08:00(UTC-7) ###### 題解 + Q&A ###### 還沒有加入DC伺服器的請記得加入,並去查看#學員驗證頻道進行驗證才可以看到live session的討論區https://discord.gg/WUE3XutPK3 --- #### 本周題目 #### Leetcode 1052 #### https://leetcode.com/problems/grumpy-bookstore-owner/description/ #### Leetcode 802 #### https://leetcode.com/problems/find-eventual-safe-states/description/ --- ### Hint - Leetcode 1052 : - hint 1: 當決定好,要在哪一段時間使用 secret technical 後,那段時間的 grumpy 就不重要了 ---- ### Hint - Leetcode 1052 : - hint 1: 當決定好,要在哪一段時間使用 secret technical 後,那段時間的 grumpy 就不重要了 - hint 2: 會需要計算兩種區間和,一種是不管 grumpy 的,一種是要管 grumpy 的 ---- ### Hint - Leetcode 1052 : - hint 1: 當決定好,要在哪一段時間使用 secret technical 後,那段時間的 grumpy 就不重要了 - hint 2: 會需要計算兩種區間和,一種是不管 grumpy 的,一種是要管 grumpy 的 - hint 3: 可能不能馬上決定要在哪一段時間使用 secret technical,那就所有可能嘗試候選最好的 ---- ### Hint - Leetcode 1052 : - ###### hint 1: 當決定好,要在哪一段時間使用 secret technical 後,那段時間的 grumpy 就不重要了 - ###### hint 2: 會需要計算兩種區間和,一種是不管 grumpy 的,一種是要管 grumpy 的 - ###### hint 3: 可能不能馬上決定要在哪一段時間使用 secret technical,那就所有可能嘗試候選最好的 - ###### hint 4: 假設要在 l,r 中間使用 secret technical,那總和就會是 sum1[l..r] + sum2[0..l-1] + sum2[r+1,n-1],其中 sum1 是不考慮 grumpy 的,而 sum2 要考慮 --- ### Hint - Leetcode 802 : - hint 1: terminal 的點就是 safety node ---- ### Hint - Leetcode 802 : - hint 1: terminal 的點就是 safety node - hint 2: 一個點如果他所有指出去的邊都是 safety node,那他就是 safety node ---- ### Hint - Leetcode 802 : - hint 1: terminal 的點就是 safety node - hint 2: 一個點如果他所有指出去的邊都是 safety node,那他就是 safety node - hint 3: 如果判斷出一個點是 safety node,那可以向所有指向他的人,更新他們指出去的點 safety node又多一個。 ---- ### Hint - Leetcode 802 : - ###### hint 1: terminal 的點就是 safety node - ###### hint 2: 一個點如果他所有指出去的邊都是 safety node,那他就是 safety node - ###### hint 3: 如果判斷出一個點是 safety node,那可以向所有指向他的人,更新他們指出去的點 safety node又多一個。 - ###### hint 4: 根據 hint 3,若把邊反過來可能會比較好做 ---- ### Hint - Leetcode 802 : - ###### hint 1: terminal 的點就是 safety node - ###### hint 2: 一個點如果他所有指出去的邊都是 safety node,那他就是 safety node - ###### hint 3: 如果判斷出一個點是 safety node,那可以向所有指向他的人,更新他們指出去的點 safety node又多一個。 - ###### hint 4: 根據 hint 3,若把邊反過來可能會比較好做 - ###### hint 5: 想像把已經是 safety node 的點拔掉 --- ### 題解 ---- ### Leetcode 1052 題目 - 有一家書店會開 $n$ 分鐘,第 $i$ 分鐘會有 customer[$i$]個人進來 - 老闆在某些分鐘會脾氣暴躁,這個時間進來的客人會對書店不滿意,其他時候進來的客人會對書店滿意 - 老闆有一個秘密科技可以讓他保證在接下來連續 $minutes$ 分鐘脾氣不暴躁 - 問最多可以讓多少客人滿意 ---- ### Leetcode 1052 題目 - customer = [1,2,3,4] - grumpy = [0,1,0,1] ---- ### Leetcode 1052 - 我們可以用一個新的 array 去紀錄不使用科技的情況下,每分鐘滿意的客人 satisfiedCustomer[i] = costomer[i] * ( 1 - grumpy[i]) - 當我們使用科技在 [l..r] 的區間時,滿意的客人數量為 satisfiedCustomer[0...l-1] + customer[l...r] + satisfiedCustomer[r+1...n-1] - 只有n種可能使用科技的方法,剩下的可以用 prefix sum 求解直到找到最好的一個 ---- ### LeetCode 1052 java code ```java //time complexity: O(n) //Extra space complexity: O(n) public int maxSatisfied(int[] customers, int[] grumpy, int minutes) { int n = customers.length; int[] satisfiedCustomer = new int[n + 1]; int[] originCustomer = new int[n + 1]; for (int i = 0; i < n; i++) { satisfiedCustomer[i + 1] = satisfiedCustomer[i] + customers[i] * (1 - grumpy[i]); originCustomer[i + 1] = originCustomer[i] + customers[i]; } int ans = 0; for (int i = 0; i + minutes <= n; i++) { int cur = satisfiedCustomer[i] + (originCustomer[i + minutes] - originCustomer[i]) + (satisfiedCustomer[n] - satisfiedCustomer[i + minutes]); ans = Math.max(ans, cur); } return ans; } ``` ---- ### Test case - grumpy 全部都 1 - grumpy 全部都 0 - normal case - customer = [1,2,3,4] - grumpy = [0,1,0,1] - minutes = 2 ---- ### Leetcode 802 題目 - 給一張有向圖,定義一個點當它沒有 out edge 時為 terminal。 - 而定義一個點,當沿著他的邊一直走,沒辦法無限走下去時,為 safety node。 ---- ### Leetcode 802 題目 ![image](https://hackmd.io/_uploads/BkHvSJizWe.png) ---- ### Leetcode 802 解法 - 當一個點為 terminal 時,他為 safety node. - 當我們把一個點判斷為 safety node 後可以把它從圖上拔掉,而新的圖若存在一個點為 terminal 時,他也會為 safety node。 - 每次都把 out degree 為 0 的點拔掉,當拔掉一個點的時候,把所有指向他的點的 out degree - 1。 - 做完上述操作後,有點的 out degree 變成 0 時,也把它拔掉 - 可以用 queue 去儲存即將要被拔掉的點並作上述處理 ---- ### Leetcode 802 java code ```java //time complexity: O(n+m) //Extra space complexity: O(n) public List<Integer> eventualSafeNodes(int[][] graph) { int n = graph.length; List<List<Integer>> rgraph = new ArrayList<>(); for (int i = 0; i < n; i++) { rgraph.add(new ArrayList<>()); } int[] degree = new int[n]; for (int i = 0; i < n; i++) { degree[i] = graph[i].length; for (int v : graph[i]) { rgraph.get(v).add(i); } } Queue<Integer> q = new ArrayDeque<>(); for (int i = 0; i < n; i++) { if (degree[i] == 0) { q.offer(i); } } List<Integer> ans = new ArrayList<>(); while (!q.isEmpty()) { int x = q.poll(); ans.add(x); for (int prev : rgraph.get(x)) { if (--degree[prev] == 0) { q.offer(prev); } } } Collections.sort(ans); return ans; } ``` ---- ### Test case - 所有點都是 safety node - 所有點都不是 safety node - 自己走到自己 ---- ### 幫忙填寫個回饋問卷讓我們變得更好 - https://forms.gle/fnESLNH69v2vzBUt7 - ![image](https://hackmd.io/_uploads/rJLxExsGbx.png)
{"title":"1213 live session","description":"Leetcode 2451 :","contributors":"[{\"id\":\"4121b533-a197-44b5-b406-dab56911778d\",\"add\":10914,\"del\":5439,\"latestUpdatedAt\":1765640710848}]"}
    98 views