置頂

GeoGebra 文章目錄

GeoGebra 文章目錄  更新日期:2018/2/8 我將 GeoGebra 相關的文章及檔案連結都整理在這篇裡,之後如果有新的文章也會同時更新這個目錄。上傳到 GeoGebraTube 的檔案,我有試著用 Google Chrome 63.0.3239.13...

熱門文章

2026年6月2日 星期二

LeetCode 解題筆記:3633. Earliest Finish Time for Land and Water Rides I

作者:王一哲
日期:2026年6月2日


LeetCode 題目連結:3633. Earliest Finish Time for Land and Water Rides I

解題想法


簡單難度的題目。我先將合併開始、經過時刻,組成 (結束時刻, 開始時刻) 串列。測試兩種可能性,找出先去 land 再去 water 的最早結束時刻 t1,以及先去 water 再去 land 的最早結束時刻 t2,回傳 t1, t2 較小者。可以過關但速度不夠快,還可以再改進。

Python 程式碼


Runtime: 155 ms, beats 52.33%. Memory: 19.29 MB, beats 86.05%.
class Solution:
    def earliestFinishTime(self, landStartTime: List[int], landDuration: List[int], waterStartTime: List[int], waterDuration: List[int]) -> int:
        # 合併開始、經過時刻,組成 (結束時刻, 開始時刻) 
        landFinishTime = [(s + d, s) for s, d, in zip(landStartTime, landDuration)]
        waterFinishTime = [(s + d, s) for s , d in zip(waterStartTime, waterDuration)]
        # 先去 land 再去 water 的最早結束時刻
        t1 = float('inf')
        for landF, _ in landFinishTime:
            for waterF, waterS in waterFinishTime:
                t = waterF  # 預設為 waterF
                if landF > waterS:  # 如果 landF 大於 waterS,需要多等一段時間
                    t += landF - waterS
                if t < t1: t1 = t
        # 先去 water 再去 land 的最早結束時刻
        t2 = float('inf')
        for waterF, _ in waterFinishTime:
            for landF, landS in landFinishTime:
                t = landF  # 預設為 landF
                if waterF > landS:  # 如果 waterF 大於 landS,需要多等一段時間
                    t += waterF - landS
                if t < t2: t2 = t
        return min(t1, t2)  # 取 (t1, t2) 較小者

不合併資料,用兩層 for 迴圈掃過串列,速度反而慢很多。Runtime: 355 ms, beats 5.23%. Memory: 19.38 MB, beats 56.98%.

class Solution:
    def earliestFinishTime(self, landStartTime: List[int], landDuration: List[int], waterStartTime: List[int], waterDuration: List[int]) -> int:
        n, m = len(landStartTime), len(waterStartTime)
        # 先去 land 再去 water 的最早結束時刻
        t1 = float('inf')
        for i in range(n):
            for j in range(m):
                t = waterStartTime[j] + waterDuration[j]  # 預設為 waterF
                if landStartTime[i] + landDuration[i] > waterStartTime[j]:  # 如果 landF 大於 waterS,需要多等一段時間
                    t += landStartTime[i] + landDuration[i] - waterStartTime[j]
                if t < t1: t1 = t
        # 先去 water 再去 land 的最早結束時刻
        t2 = float('inf')
        for i in range(m):
            for j in range(n):
                t = landStartTime[j] + landDuration[j]  # 預設為 landF
                if waterStartTime[i] + waterDuration[i] > landStartTime[j]:  # 如果 waterF 大於 landS,需要多等一段時間
                    t += waterStartTime[i] + waterDuration[i] - landStartTime[j]
                if t < t2: t2 = t
        return min(t1, t2)  # 取 (t1, t2) 較小者


C++ 程式碼


Runtime: 8 ms, beats 46.41%. Memory: 93.40 MB, beats 8.44%.
class Solution {
public:
    int earliestFinishTime(vector<int>& landStartTime, vector<int>& landDuration, vector<int>& waterStartTime, vector<int>& waterDuration) {
        // 合併開始、經過時刻,組成 (結束時刻, 開始時刻) 
        vector<pair<int, int>> landFinishTime, waterFinishTime;
        int n = (int)landStartTime.size(), m = (int)waterStartTime.size();
        for(int i=0; i<n; i++) {
            landFinishTime.push_back(make_pair(landStartTime[i] + landDuration[i], landStartTime[i]));
        }
        for(int i=0; i<m; i++) {
            waterFinishTime.push_back(make_pair(waterStartTime[i] + waterDuration[i], waterStartTime[i]));
        }
        // 先去 land 再去 water 的最早結束時刻
        int t1 = 1000000000;
        for(auto it_land : landFinishTime) {
            for(auto it_water : waterFinishTime) {
                int t = it_water.first;  // 預設為 waterF
                if (it_land.first > it_water.second) {  // 如果 landF 大於 waterS,需要多等一段時間
                    t += it_land.first - it_water.second;
                }
                if (t < t1) t1 = t;
            }
        }
        // 先去 water 再去 land 的最早結束時刻
        int t2 = 1000000000;
        for(auto it_water : waterFinishTime) {
            for(auto it_land : landFinishTime) {
                int t = it_land.first;  // 預設為 landF
                if (it_water.first > it_land.second) {  // 如果 waterF 大於 landS,需要多等一段時間
                    t += it_water.first - it_land.second;
                }
                if (t < t2) t2 = t;
            }
        }
        return min(t1, t2);  // 取 (t1, t2) 較小者
    }
};

不要先合併資料,速度比較快。Runtime: 3 ms, beats 71.31%. Memory: 91.88 MB, beats 59.92%.

class Solution {
public:
    int earliestFinishTime(vector<int>& landStartTime, vector<int>& landDuration, vector<int>& waterStartTime, vector<int>& waterDuration) {
        int n = (int)landStartTime.size(), m = (int)waterStartTime.size();
        // 先去 land 再去 water 的最早結束時刻
        int t1 = 1000000000;
        for(int i=0; i<n; i++) {
            for(int j=0; j<m; j++) {
                int t = waterStartTime[j] + waterDuration[j];  // 預設為 waterF
                if (landStartTime[i] + landDuration[i] > waterStartTime[j]) {  // 如果 landF 大於 waterS,需要多等一段時間
                    t += landStartTime[i] + landDuration[i] - waterStartTime[j];
                }
                if (t < t1) t1 = t;
            }
        }
        // 先去 water 再去 land 的最早結束時刻
        int t2 = 1000000000;
        for(int i=0; i<m; i++) {
            for(int j=0; j<n; j++) {
                int t = landStartTime[j] + landDuration[j];  // 預設為 landF
                if (waterStartTime[i] + waterDuration[i] > landStartTime[j]) {  // 如果 waterF 大於 landS,需要多等一段時間
                    t += waterStartTime[i] + waterDuration[i] - landStartTime[j];
                }
                if (t < t2) t2 = t;
            }
        }
        return min(t1, t2);  // 取 (t1, t2) 較小者
    }
};

沒有留言:

張貼留言