diff --git a/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/1.png b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/1.png new file mode 100644 index 000000000..071ca8c27 Binary files /dev/null and b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/1.png differ diff --git a/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/2.png b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/2.png new file mode 100644 index 000000000..201df6b2e Binary files /dev/null and b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/2.png differ diff --git a/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/3.png b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/3.png new file mode 100644 index 000000000..d1022c1b2 Binary files /dev/null and b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/3.png differ diff --git a/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/README.md b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/README.md index 9df242b73..e7d67a3bb 100755 --- a/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/README.md +++ b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/README.md @@ -1,28 +1,41 @@ # [2054.Two Best Non-Overlapping Events][title] -> [!WARNING|style:flat] -> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm) - ## Description +You are given a **0-indexed** 2D integer array of `events` where `events[i] = [startTimei, endTimei, valuei]`. The `ith` event starts at `startTimei` and ends at `endTimei`, and if you attend this event, you will receive a value of `valuei`. You can choose **at most two non-overlapping** events to attend such that the sum of their values is **maximized**. + +Return this **maximum** sum. + +Note that the start time and end time is **inclusive**: that is, you cannot attend two events where one of them starts and the other ends at the same time. More specifically, if you attend an event with end time `t`, the next event must start at or after `t + 1`. -**Example 1:** +**Example 1:** + +![1](./1.png) ``` -Input: a = "11", b = "1" -Output: "100" +Input: events = [[1,3,2],[4,5,2],[2,4,3]] +Output: 4 +Explanation: Choose the green events, 0 and 1 for a sum of 2 + 2 = 4. ``` -## 题意 -> ... +**Example 2:** -## 题解 +![2](./2.png) -### 思路1 -> ... -Two Best Non-Overlapping Events -```go +``` +Input: events = [[1,3,2],[4,5,2],[1,5,5]] +Output: 5 +Explanation: Choose event 2 for a sum of 5. ``` +**Example 3:** + +![3](./3.png) + +``` +Input: events = [[1,5,3],[1,5,1],[6,6,5]] +Output: 8 +Explanation: Choose events 0 and 2 for a sum of 3 + 5 = 8. +``` ## 结语 diff --git a/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/Solution.go b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/Solution.go index d115ccf5e..6d652e630 100644 --- a/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/Solution.go +++ b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/Solution.go @@ -1,5 +1,58 @@ package Solution -func Solution(x bool) bool { - return x +import "sort" + +type SegmentTreeNode2054 struct { + Left, Right, Max int + LeftChild, RightChild *SegmentTreeNode2054 +} + +func buildSegmentTree2054(nums [][]int, left, right int) *SegmentTreeNode2054 { + if left == right { + return &SegmentTreeNode2054{Left: left, Right: right, Max: nums[left][2]} + } + + mid := (left + right) / 2 + leftNode := buildSegmentTree2054(nums, left, mid) + rightNode := buildSegmentTree2054(nums, mid+1, right) + max := max(leftNode.Max, rightNode.Max) + + return &SegmentTreeNode2054{Left: left, Right: right, Max: max, LeftChild: leftNode, RightChild: rightNode} +} + +func queryMax2054(root *SegmentTreeNode2054, left, right int) int { + if root.Left >= left && root.Right <= right { + return root.Max + } + + if root.Right < left || root.Left > right { + return -1 + } + + return max(queryMax2054(root.LeftChild, left, right), queryMax2054(root.RightChild, left, right)) +} + +func Solution(events [][]int) int { + sort.Slice(events, func(i, j int) bool { + a, b := events[i], events[j] + if a[0] == b[0] { + return a[1] < b[1] + } + return a[0] < b[0] + }) + l := len(events) + + tree := buildSegmentTree2054(events, 0, l-1) + ans := 0 + for i, e := range events { + ans = max(ans, e[2]) + idx := sort.Search(l-i-1, func(ii int) bool { + return events[i+1+ii][0] > e[1] + }) + if idx == l-i-1 { + continue + } + ans = max(ans, e[2]+queryMax2054(tree, i+1+idx, l-1)) + } + return ans } diff --git a/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/Solution_test.go b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/Solution_test.go index 14ff50eb4..c5381384c 100644 --- a/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/Solution_test.go +++ b/leetcode/2001-2100/2054.Two-Best-Non-Overlapping-Events/Solution_test.go @@ -10,12 +10,12 @@ func TestSolution(t *testing.T) { // 测试用例 cases := []struct { name string - inputs bool - expect bool + inputs [][]int + expect int }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", [][]int{{1, 3, 2}, {4, 5, 2}, {2, 4, 3}}, 4}, + {"TestCase2", [][]int{{1, 3, 2}, {4, 5, 2}, {1, 5, 5}}, 5}, + {"TestCase3", [][]int{{1, 5, 3}, {1, 5, 1}, {6, 6, 5}}, 8}, } // 开始测试 @@ -30,10 +30,10 @@ func TestSolution(t *testing.T) { } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }