From 8c83bba49c9891eafb72031709c9d341593a56a4 Mon Sep 17 00:00:00 2001 From: 0xff-dev Date: Sun, 23 Jun 2024 11:50:23 +0800 Subject: [PATCH] Add solution and test-cases for problem 1438 --- .../README.md | 45 +++++++++ .../Solution.go | 96 ++++++++++++++++++- .../Solution_test.go | 22 +++-- 3 files changed, 151 insertions(+), 12 deletions(-) create mode 100644 leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/README.md diff --git a/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/README.md b/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/README.md new file mode 100644 index 00000000..97d28082 --- /dev/null +++ b/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/README.md @@ -0,0 +1,45 @@ +# [1438.Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit][title] + +## Description +Given an array of integers `nums` and an integer `limit`, return the size of the longest **non-empty** subarray such that the absolute difference between any two elements of this subarray is less than or equal to `limit`. + +**Example 1:** + +``` +Input: nums = [8,2,4,7], limit = 4 +Output: 2 +Explanation: All subarrays are: +[8] with maximum absolute diff |8-8| = 0 <= 4. +[8,2] with maximum absolute diff |8-2| = 6 > 4. +[8,2,4] with maximum absolute diff |8-2| = 6 > 4. +[8,2,4,7] with maximum absolute diff |8-2| = 6 > 4. +[2] with maximum absolute diff |2-2| = 0 <= 4. +[2,4] with maximum absolute diff |2-4| = 2 <= 4. +[2,4,7] with maximum absolute diff |2-7| = 5 > 4. +[4] with maximum absolute diff |4-4| = 0 <= 4. +[4,7] with maximum absolute diff |4-7| = 3 <= 4. +[7] with maximum absolute diff |7-7| = 0 <= 4. +Therefore, the size of the longest subarray is 2. +``` + +**Example 2:** + +``` +Input: nums = [10,1,2,4,7,2], limit = 5 +Output: 4 +Explanation: The subarray [2,4,7,2] is the longest since the maximum absolute diff is |2-7| = 5 <= 5. +``` + +**Example 3:** + +``` +Input: nums = [4,2,2,2,4,4,2,2], limit = 0 +Output: 3 +``` + +## 结语 + +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-algorithm][me] + +[title]: https://leetcode.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit +[me]: https://github.com/kylesliu/awesome-golang-algorithm diff --git a/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/Solution.go b/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/Solution.go index d115ccf5..a4e289d5 100755 --- a/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/Solution.go +++ b/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/Solution.go @@ -1,5 +1,97 @@ package Solution -func Solution(x bool) bool { - return x +type SegmentTreeNode1438 struct { + Left, Right int + Min, Max int + LeftChild *SegmentTreeNode1438 + RightChild *SegmentTreeNode1438 +} + +func buildSegmentTree1438(arr []int, left, right int) *SegmentTreeNode1438 { + if left == right { + return &SegmentTreeNode1438{ + Left: left, + Right: right, + Min: arr[left], + Max: arr[left], + } + } + + mid := (left + right) / 2 + leftChild := buildSegmentTree1438(arr, left, mid) + rightChild := buildSegmentTree1438(arr, mid+1, right) + + node := &SegmentTreeNode1438{ + Left: left, + Right: right, + Min: min(leftChild.Min, rightChild.Min), + Max: max(leftChild.Max, rightChild.Max), + LeftChild: leftChild, + RightChild: rightChild, + } + + return node +} + +func queryMin1438(node *SegmentTreeNode1438, left, right int) int { + if node.Left == left && node.Right == right { + return node.Min + } + + mid := (node.Left + node.Right) / 2 + + if right <= mid { + return queryMin1438(node.LeftChild, left, right) + } else if left > mid { + return queryMin1438(node.RightChild, left, right) + } else { + leftMin := queryMin1438(node.LeftChild, left, mid) + rightMin := queryMin1438(node.RightChild, mid+1, right) + return min(leftMin, rightMin) + } +} + +func queryMax1438(node *SegmentTreeNode1438, left, right int) int { + if node.Left == left && node.Right == right { + return node.Max + } + + mid := (node.Left + node.Right) / 2 + + if right <= mid { + return queryMax1438(node.LeftChild, left, right) + } else if left > mid { + return queryMax1438(node.RightChild, left, right) + } else { + leftMax := queryMax1438(node.LeftChild, left, mid) + rightMax := queryMax1438(node.RightChild, mid+1, right) + return max(leftMax, rightMax) + } +} + +// 滑动窗口, 线段树? +func Solution(nums []int, limit int) int { + l := len(nums) + tree := buildSegmentTree1438(nums, 0, l-1) + start, end := 0, 0 + ans := 0 + + var a, b int + for ; end < l; end++ { + a = queryMax1438(tree, start, end) + b = queryMin1438(tree, start, end) + if a-b <= limit { + ans = max(ans, end-start+1) + continue + } + for start < end { + start++ + a = queryMax1438(tree, start, end) + b = queryMin1438(tree, start, end) + if a-b <= limit { + break + } + } + } + return ans } diff --git a/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/Solution_test.go b/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/Solution_test.go index 14ff50eb..e372d2b3 100755 --- a/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/Solution_test.go +++ b/leetcode/1401-1500/1438.Longest-Continuous-Subarray-With-Absolute-Diff-Less-Than-or-Equal-to-Limit/Solution_test.go @@ -10,30 +10,32 @@ func TestSolution(t *testing.T) { // 测试用例 cases := []struct { name string - inputs bool - expect bool + nums []int + limit int + expect int }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", []int{8, 2, 4, 7}, 4, 2}, + {"TestCase2", []int{10, 1, 2, 4, 7, 2}, 5, 4}, + {"TestCase3", []int{4, 2, 2, 2, 4, 4, 2, 2}, 0, 3}, + {"TestCase4", []int{24, 12, 71, 33, 5, 87, 10, 11, 3, 58, 2, 97, 97, 36, 32, 35, 15, 80, 24, 45, 38, 9, 22, 21, 33, 68, 22, 85, 35, 83, 92, 38, 59, 90, 42, 64, 61, 15, 4, 40, 50, 44, 54, 25, 34, 14, 33, 94, 66, 27, 78, 56, 3, 29, 3, 51, 19, 5, 93, 21, 58, 91, 65, 87, 55, 70, 29, 81, 89, 67, 58, 29, 68, 84, 4, 51, 87, 74, 42, 85, 81, 55, 8, 95, 39}, 87, 25}, } // 开始测试 for i, c := range cases { t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { - got := Solution(c.inputs) + got := Solution(c.nums, c.limit) if !reflect.DeepEqual(got, c.expect) { - t.Fatalf("expected: %v, but got: %v, with inputs: %v", - c.expect, got, c.inputs) + t.Fatalf("expected: %v, but got: %v, with inputs: %v %v", + c.expect, got, c.nums, c.limit) } }) } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }