diff --git a/solution/0700-0799/0759.Employee Free Time/README.md b/solution/0700-0799/0759.Employee Free Time/README.md index e422bbd125252..061cde2bfb2cc 100644 --- a/solution/0700-0799/0759.Employee Free Time/README.md +++ b/solution/0700-0799/0759.Employee Free Time/README.md @@ -68,32 +68,237 @@ tags: -### 方法一 +### 方法一:区间合并 + +我们可以将所有员工的工作时间区间合并成一个列表,然后对该列表进行排序并合并重叠的区间。最后,遍历合并后的区间列表,找出相邻区间之间的空闲时间段。 + +时间复杂度 $O(m \times n \times \log(m \times n))$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为员工数量和每个员工的工作时间区间数量。 #### Python3 ```python - +""" +# Definition for an Interval. +class Interval: + def __init__(self, start: int = None, end: int = None): + self.start = start + self.end = end +""" + + +class Solution: + def employeeFreeTime(self, schedule: "[[Interval]]") -> "[Interval]": + intervals = [] + for e in schedule: + intervals.extend(e) + intervals.sort(key=lambda x: (x.start, x.end)) + merged = [intervals[0]] + for x in intervals[1:]: + if merged[-1].end < x.start: + merged.append(x) + else: + merged[-1].end = max(merged[-1].end, x.end) + ans = [] + for a, b in pairwise(merged): + ans.append(Interval(a.end, b.start)) + return ans ``` #### Java ```java - +/* +// Definition for an Interval. +class Interval { + public int start; + public int end; + + public Interval() {} + + public Interval(int _start, int _end) { + start = _start; + end = _end; + } +}; +*/ + +class Solution { + public List employeeFreeTime(List> schedule) { + List intervals = new ArrayList<>(); + for (List e : schedule) { + intervals.addAll(e); + } + + intervals.sort((a, b) -> a.start == b.start ? a.end - b.end : a.start - b.start); + + List merged = new ArrayList<>(); + merged.add(intervals.get(0)); + for (int i = 1; i < intervals.size(); ++i) { + Interval last = merged.get(merged.size() - 1); + Interval cur = intervals.get(i); + if (last.end < cur.start) { + merged.add(cur); + } else { + last.end = Math.max(last.end, cur.end); + } + } + + List ans = new ArrayList<>(); + for (int i = 1; i < merged.size(); ++i) { + Interval a = merged.get(i - 1); + Interval b = merged.get(i); + ans.add(new Interval(a.end, b.start)); + } + + return ans; + } +} ``` #### C++ ```cpp - +/* +// Definition for an Interval. +class Interval { +public: + int start; + int end; + + Interval() {} + + Interval(int _start, int _end) { + start = _start; + end = _end; + } +}; +*/ + +class Solution { +public: + vector employeeFreeTime(vector> schedule) { + vector intervals; + for (auto& e : schedule) { + intervals.insert(intervals.end(), e.begin(), e.end()); + } + + sort(intervals.begin(), intervals.end(), [](const Interval& a, const Interval& b) { + if (a.start == b.start) return a.end < b.end; + return a.start < b.start; + }); + + vector merged; + merged.push_back(intervals[0]); + for (int i = 1; i < intervals.size(); ++i) { + auto& last = merged.back(); + auto& cur = intervals[i]; + if (last.end < cur.start) { + merged.push_back(cur); + } else { + last.end = max(last.end, cur.end); + } + } + + vector ans; + for (int i = 1; i < merged.size(); ++i) { + auto& a = merged[i - 1]; + auto& b = merged[i]; + ans.emplace_back(a.end, b.start); + } + + return ans; + } +}; ``` #### Go ```go +/** + * Definition for an Interval. + * type Interval struct { + * Start int + * End int + * } + */ + +func employeeFreeTime(schedule [][]*Interval) []*Interval { + var intervals []*Interval + for _, e := range schedule { + intervals = append(intervals, e...) + } + + sort.Slice(intervals, func(i, j int) bool { + if intervals[i].Start == intervals[j].Start { + return intervals[i].End < intervals[j].End + } + return intervals[i].Start < intervals[j].Start + }) + + merged := []*Interval{intervals[0]} + for _, cur := range intervals[1:] { + last := merged[len(merged)-1] + if last.End < cur.Start { + merged = append(merged, cur) + } else if cur.End > last.End { + last.End = cur.End + } + } + + var ans []*Interval + for i := 1; i < len(merged); i++ { + a, b := merged[i-1], merged[i] + ans = append(ans, &Interval{Start: a.End, End: b.Start}) + } + + return ans +} +``` +#### TypeScript + +```ts +/** + * // Definition for an Interval. + * class Interval { + * start: number; + * end: number; + * constructor(start: number, end: number) { + * this.start = start; + * this.end = end; + * } + * } + */ +function employeeFreeTime(schedule: Interval[][]): Interval[] { + const intervals: Interval[] = []; + for (const e of schedule) { + intervals.push(...e); + } + + intervals.sort((a, b) => (a.start === b.start ? a.end - b.end : a.start - b.start)); + + const merged: Interval[] = [intervals[0]]; + for (let i = 1; i < intervals.length; ++i) { + const last = merged[merged.length - 1]; + const cur = intervals[i]; + if (last.end < cur.start) { + merged.push(cur); + } else { + last.end = Math.max(last.end, cur.end); + } + } + + const ans: Interval[] = []; + for (let i = 1; i < merged.length; ++i) { + const a = merged[i - 1]; + const b = merged[i]; + ans.push(new Interval(a.end, b.start)); + } + + return ans; +} ``` diff --git a/solution/0700-0799/0759.Employee Free Time/README_EN.md b/solution/0700-0799/0759.Employee Free Time/README_EN.md index 7c0a64ed0b949..b1cdf44a0148a 100644 --- a/solution/0700-0799/0759.Employee Free Time/README_EN.md +++ b/solution/0700-0799/0759.Employee Free Time/README_EN.md @@ -59,32 +59,237 @@ We discard any intervals that contain inf as they aren't finite. -### Solution 1 +### Solution 1: Interval Merging + +We can merge all employees' working time intervals into a single list, then sort and merge the overlapping intervals. Finally, we traverse the merged interval list to find the free time periods between adjacent intervals. + +The time complexity is $O(mn \log(mn))$ and the space complexity is $O(mn)$, where $m$ is the number of employees and $n$ is the number of working intervals per employee. #### Python3 ```python - +""" +# Definition for an Interval. +class Interval: + def __init__(self, start: int = None, end: int = None): + self.start = start + self.end = end +""" + + +class Solution: + def employeeFreeTime(self, schedule: "[[Interval]]") -> "[Interval]": + intervals = [] + for e in schedule: + intervals.extend(e) + intervals.sort(key=lambda x: (x.start, x.end)) + merged = [intervals[0]] + for x in intervals[1:]: + if merged[-1].end < x.start: + merged.append(x) + else: + merged[-1].end = max(merged[-1].end, x.end) + ans = [] + for a, b in pairwise(merged): + ans.append(Interval(a.end, b.start)) + return ans ``` #### Java ```java - +/* +// Definition for an Interval. +class Interval { + public int start; + public int end; + + public Interval() {} + + public Interval(int _start, int _end) { + start = _start; + end = _end; + } +}; +*/ + +class Solution { + public List employeeFreeTime(List> schedule) { + List intervals = new ArrayList<>(); + for (List e : schedule) { + intervals.addAll(e); + } + + intervals.sort((a, b) -> a.start == b.start ? a.end - b.end : a.start - b.start); + + List merged = new ArrayList<>(); + merged.add(intervals.get(0)); + for (int i = 1; i < intervals.size(); ++i) { + Interval last = merged.get(merged.size() - 1); + Interval cur = intervals.get(i); + if (last.end < cur.start) { + merged.add(cur); + } else { + last.end = Math.max(last.end, cur.end); + } + } + + List ans = new ArrayList<>(); + for (int i = 1; i < merged.size(); ++i) { + Interval a = merged.get(i - 1); + Interval b = merged.get(i); + ans.add(new Interval(a.end, b.start)); + } + + return ans; + } +} ``` #### C++ ```cpp - +/* +// Definition for an Interval. +class Interval { +public: + int start; + int end; + + Interval() {} + + Interval(int _start, int _end) { + start = _start; + end = _end; + } +}; +*/ + +class Solution { +public: + vector employeeFreeTime(vector> schedule) { + vector intervals; + for (auto& e : schedule) { + intervals.insert(intervals.end(), e.begin(), e.end()); + } + + sort(intervals.begin(), intervals.end(), [](const Interval& a, const Interval& b) { + if (a.start == b.start) return a.end < b.end; + return a.start < b.start; + }); + + vector merged; + merged.push_back(intervals[0]); + for (int i = 1; i < intervals.size(); ++i) { + auto& last = merged.back(); + auto& cur = intervals[i]; + if (last.end < cur.start) { + merged.push_back(cur); + } else { + last.end = max(last.end, cur.end); + } + } + + vector ans; + for (int i = 1; i < merged.size(); ++i) { + auto& a = merged[i - 1]; + auto& b = merged[i]; + ans.emplace_back(a.end, b.start); + } + + return ans; + } +}; ``` #### Go ```go +/** + * Definition for an Interval. + * type Interval struct { + * Start int + * End int + * } + */ + +func employeeFreeTime(schedule [][]*Interval) []*Interval { + var intervals []*Interval + for _, e := range schedule { + intervals = append(intervals, e...) + } + + sort.Slice(intervals, func(i, j int) bool { + if intervals[i].Start == intervals[j].Start { + return intervals[i].End < intervals[j].End + } + return intervals[i].Start < intervals[j].Start + }) + + merged := []*Interval{intervals[0]} + for _, cur := range intervals[1:] { + last := merged[len(merged)-1] + if last.End < cur.Start { + merged = append(merged, cur) + } else if cur.End > last.End { + last.End = cur.End + } + } + + var ans []*Interval + for i := 1; i < len(merged); i++ { + a, b := merged[i-1], merged[i] + ans = append(ans, &Interval{Start: a.End, End: b.Start}) + } + + return ans +} +``` +#### TypeScript + +```ts +/** + * // Definition for an Interval. + * class Interval { + * start: number; + * end: number; + * constructor(start: number, end: number) { + * this.start = start; + * this.end = end; + * } + * } + */ +function employeeFreeTime(schedule: Interval[][]): Interval[] { + const intervals: Interval[] = []; + for (const e of schedule) { + intervals.push(...e); + } + + intervals.sort((a, b) => (a.start === b.start ? a.end - b.end : a.start - b.start)); + + const merged: Interval[] = [intervals[0]]; + for (let i = 1; i < intervals.length; ++i) { + const last = merged[merged.length - 1]; + const cur = intervals[i]; + if (last.end < cur.start) { + merged.push(cur); + } else { + last.end = Math.max(last.end, cur.end); + } + } + + const ans: Interval[] = []; + for (let i = 1; i < merged.length; ++i) { + const a = merged[i - 1]; + const b = merged[i]; + ans.push(new Interval(a.end, b.start)); + } + + return ans; +} ``` diff --git a/solution/0700-0799/0759.Employee Free Time/Solution.cpp b/solution/0700-0799/0759.Employee Free Time/Solution.cpp new file mode 100644 index 0000000000000..703ac94ab2467 --- /dev/null +++ b/solution/0700-0799/0759.Employee Free Time/Solution.cpp @@ -0,0 +1,51 @@ +/* +// Definition for an Interval. +class Interval { +public: + int start; + int end; + + Interval() {} + + Interval(int _start, int _end) { + start = _start; + end = _end; + } +}; +*/ + +class Solution { +public: + vector employeeFreeTime(vector> schedule) { + vector intervals; + for (auto& e : schedule) { + intervals.insert(intervals.end(), e.begin(), e.end()); + } + + sort(intervals.begin(), intervals.end(), [](const Interval& a, const Interval& b) { + if (a.start == b.start) return a.end < b.end; + return a.start < b.start; + }); + + vector merged; + merged.push_back(intervals[0]); + for (int i = 1; i < intervals.size(); ++i) { + auto& last = merged.back(); + auto& cur = intervals[i]; + if (last.end < cur.start) { + merged.push_back(cur); + } else { + last.end = max(last.end, cur.end); + } + } + + vector ans; + for (int i = 1; i < merged.size(); ++i) { + auto& a = merged[i - 1]; + auto& b = merged[i]; + ans.emplace_back(a.end, b.start); + } + + return ans; + } +}; diff --git a/solution/0700-0799/0759.Employee Free Time/Solution.go b/solution/0700-0799/0759.Employee Free Time/Solution.go new file mode 100644 index 0000000000000..3a72c5c08c25f --- /dev/null +++ b/solution/0700-0799/0759.Employee Free Time/Solution.go @@ -0,0 +1,39 @@ +/** + * Definition for an Interval. + * type Interval struct { + * Start int + * End int + * } + */ + +func employeeFreeTime(schedule [][]*Interval) []*Interval { + var intervals []*Interval + for _, e := range schedule { + intervals = append(intervals, e...) + } + + sort.Slice(intervals, func(i, j int) bool { + if intervals[i].Start == intervals[j].Start { + return intervals[i].End < intervals[j].End + } + return intervals[i].Start < intervals[j].Start + }) + + merged := []*Interval{intervals[0]} + for _, cur := range intervals[1:] { + last := merged[len(merged)-1] + if last.End < cur.Start { + merged = append(merged, cur) + } else if cur.End > last.End { + last.End = cur.End + } + } + + var ans []*Interval + for i := 1; i < len(merged); i++ { + a, b := merged[i-1], merged[i] + ans = append(ans, &Interval{Start: a.End, End: b.Start}) + } + + return ans +} diff --git a/solution/0700-0799/0759.Employee Free Time/Solution.java b/solution/0700-0799/0759.Employee Free Time/Solution.java new file mode 100644 index 0000000000000..b15d559294ea1 --- /dev/null +++ b/solution/0700-0799/0759.Employee Free Time/Solution.java @@ -0,0 +1,46 @@ +/* +// Definition for an Interval. +class Interval { + public int start; + public int end; + + public Interval() {} + + public Interval(int _start, int _end) { + start = _start; + end = _end; + } +}; +*/ + +class Solution { + public List employeeFreeTime(List> schedule) { + List intervals = new ArrayList<>(); + for (List e : schedule) { + intervals.addAll(e); + } + + intervals.sort((a, b) -> a.start == b.start ? a.end - b.end : a.start - b.start); + + List merged = new ArrayList<>(); + merged.add(intervals.get(0)); + for (int i = 1; i < intervals.size(); ++i) { + Interval last = merged.get(merged.size() - 1); + Interval cur = intervals.get(i); + if (last.end < cur.start) { + merged.add(cur); + } else { + last.end = Math.max(last.end, cur.end); + } + } + + List ans = new ArrayList<>(); + for (int i = 1; i < merged.size(); ++i) { + Interval a = merged.get(i - 1); + Interval b = merged.get(i); + ans.add(new Interval(a.end, b.start)); + } + + return ans; + } +} diff --git a/solution/0700-0799/0759.Employee Free Time/Solution.py b/solution/0700-0799/0759.Employee Free Time/Solution.py new file mode 100644 index 0000000000000..30f47334ab821 --- /dev/null +++ b/solution/0700-0799/0759.Employee Free Time/Solution.py @@ -0,0 +1,25 @@ +""" +# Definition for an Interval. +class Interval: + def __init__(self, start: int = None, end: int = None): + self.start = start + self.end = end +""" + + +class Solution: + def employeeFreeTime(self, schedule: "[[Interval]]") -> "[Interval]": + intervals = [] + for e in schedule: + intervals.extend(e) + intervals.sort(key=lambda x: (x.start, x.end)) + merged = [intervals[0]] + for x in intervals[1:]: + if merged[-1].end < x.start: + merged.append(x) + else: + merged[-1].end = max(merged[-1].end, x.end) + ans = [] + for a, b in pairwise(merged): + ans.append(Interval(a.end, b.start)) + return ans diff --git a/solution/0700-0799/0759.Employee Free Time/Solution.ts b/solution/0700-0799/0759.Employee Free Time/Solution.ts new file mode 100644 index 0000000000000..0110d25e594f9 --- /dev/null +++ b/solution/0700-0799/0759.Employee Free Time/Solution.ts @@ -0,0 +1,39 @@ +/** + * // Definition for an Interval. + * class Interval { + * start: number; + * end: number; + * constructor(start: number, end: number) { + * this.start = start; + * this.end = end; + * } + * } + */ +function employeeFreeTime(schedule: Interval[][]): Interval[] { + const intervals: Interval[] = []; + for (const e of schedule) { + intervals.push(...e); + } + + intervals.sort((a, b) => (a.start === b.start ? a.end - b.end : a.start - b.start)); + + const merged: Interval[] = [intervals[0]]; + for (let i = 1; i < intervals.length; ++i) { + const last = merged[merged.length - 1]; + const cur = intervals[i]; + if (last.end < cur.start) { + merged.push(cur); + } else { + last.end = Math.max(last.end, cur.end); + } + } + + const ans: Interval[] = []; + for (let i = 1; i < merged.length; ++i) { + const a = merged[i - 1]; + const b = merged[i]; + ans.push(new Interval(a.end, b.start)); + } + + return ans; +}