|
52 | 52 | <li>如果你已经实现<em> </em><code>O(n)</code> 时间复杂度的解法, 请尝试设计一个 <code>O(n log(n))</code> 时间复杂度的解法。</li>
|
53 | 53 | </ul>
|
54 | 54 |
|
55 |
| - |
56 | 55 | ## 解法
|
57 | 56 |
|
58 | 57 | <!-- 这里可写通用的实现逻辑 -->
|
59 | 58 |
|
| 59 | +“前缀和 + 二分查找”,先求出数组的前缀和 `preSum`,然后根据 `preSum[i] - preSum[j] >= target` => `preSum[i] >= preSum[j] + target`,对 `preSum[i]` 进行二分查找,然后更新最小长度即可。时间复杂度 `O(n logn)`。 |
| 60 | + |
| 61 | +也可以用“滑动窗口”。 |
| 62 | + |
| 63 | +使用指针 left, right 分别表示子数组的开始位置和结束位置,维护变量 sum 表示子数组 `nums[left...right]` 元素之和。初始时 left, right 均指向 0。每一次迭代,将 `nums[right]` 加到 sum,如果此时 `sum >= target`,更新最小长度即可。然后将 sum 减去 `nums[left]`,接着 left 指针右移直至 `sum < target`。每一次迭代最后,将 right 指针右移。时间复杂度 `O(n)`。 |
| 64 | + |
60 | 65 | <!-- tabs:start -->
|
61 | 66 |
|
62 | 67 | ### **Python3**
|
63 | 68 |
|
64 | 69 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
65 | 70 |
|
| 71 | +“前缀和 + 二分查找”。 |
| 72 | + |
66 | 73 | ```python
|
| 74 | +class Solution: |
| 75 | + def minSubArrayLen(self, target: int, nums: List[int]) -> int: |
| 76 | + n = len(nums) |
| 77 | + pre_sum = [0] * (n + 1) |
| 78 | + for i in range(1, n + 1): |
| 79 | + pre_sum[i] = pre_sum[i - 1] + nums[i - 1] |
| 80 | + res = n + 1 |
| 81 | + for i in range(1, n + 1): |
| 82 | + t = pre_sum[i - 1] + target |
| 83 | + left, right = 0, n |
| 84 | + while left < right: |
| 85 | + mid = (left + right) >> 1 |
| 86 | + if pre_sum[mid] >= t: |
| 87 | + right = mid |
| 88 | + else: |
| 89 | + left = mid + 1 |
| 90 | + if pre_sum[left] - pre_sum[i - 1] >= target: |
| 91 | + res = min(res, left - i + 1) |
| 92 | + return 0 if res == n + 1 else res |
| 93 | +``` |
| 94 | + |
| 95 | +“滑动窗口”。 |
67 | 96 |
|
| 97 | +```python |
| 98 | +class Solution: |
| 99 | + def minSubArrayLen(self, target: int, nums: List[int]) -> int: |
| 100 | + n = len(nums) |
| 101 | + left = right = 0 |
| 102 | + sum, res = 0, n + 1 |
| 103 | + while right < n: |
| 104 | + sum += nums[right] |
| 105 | + while sum >= target: |
| 106 | + res = min(res, right - left + 1) |
| 107 | + sum -= nums[left] |
| 108 | + left += 1 |
| 109 | + right += 1 |
| 110 | + return 0 if res == n + 1 else res |
68 | 111 | ```
|
69 | 112 |
|
70 | 113 | ### **Java**
|
71 | 114 |
|
72 | 115 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
73 | 116 |
|
| 117 | +“前缀和 + 二分查找”。 |
| 118 | + |
74 | 119 | ```java
|
| 120 | +class Solution { |
| 121 | + public int minSubArrayLen(int target, int[] nums) { |
| 122 | + int n = nums.length; |
| 123 | + int[] preSum = new int[n + 1]; |
| 124 | + for (int i = 1; i <= n; ++i) { |
| 125 | + preSum[i] = preSum[i - 1] +nums[i - 1]; |
| 126 | + } |
| 127 | + int res = n + 1; |
| 128 | + for (int i = 1; i <= n; ++i) { |
| 129 | + int t = preSum[i - 1] + target; |
| 130 | + int left = 0, right = n; |
| 131 | + while (left < right) { |
| 132 | + int mid = (left + right) >> 1; |
| 133 | + if (preSum[mid] >= t) { |
| 134 | + right = mid; |
| 135 | + } else { |
| 136 | + left = mid + 1; |
| 137 | + } |
| 138 | + } |
| 139 | + if (preSum[left] - preSum[i - 1] >= target) { |
| 140 | + res = Math.min(res, left - i + 1); |
| 141 | + } |
| 142 | + } |
| 143 | + return res == n + 1 ? 0 : res; |
| 144 | + } |
| 145 | +} |
| 146 | +``` |
| 147 | + |
| 148 | +“滑动窗口”。 |
| 149 | + |
| 150 | +```java |
| 151 | +class Solution { |
| 152 | + public int minSubArrayLen(int target, int[] nums) { |
| 153 | + int n = nums.length; |
| 154 | + int left = 0, right = 0; |
| 155 | + int sum = 0, res = n + 1; |
| 156 | + while (right < n) { |
| 157 | + sum += nums[right]; |
| 158 | + while (sum >= target) { |
| 159 | + res = Math.min(res, right - left + 1); |
| 160 | + sum -= nums[left++]; |
| 161 | + } |
| 162 | + ++right; |
| 163 | + } |
| 164 | + return res == n + 1 ? 0 : res; |
| 165 | + } |
| 166 | +} |
| 167 | +``` |
75 | 168 |
|
| 169 | +### **C#** |
| 170 | + |
| 171 | +```cs |
| 172 | +public class Solution { |
| 173 | + public int MinSubArrayLen(int target, int[] nums) { |
| 174 | + int n = nums.Length; |
| 175 | + int left = 0, right = 0; |
| 176 | + int sum = 0, res = n + 1; |
| 177 | + while (right < n) |
| 178 | + { |
| 179 | + sum += nums[right]; |
| 180 | + while (sum >= target) |
| 181 | + { |
| 182 | + res = Math.Min(res, right - left + 1); |
| 183 | + sum -= nums[left++]; |
| 184 | + } |
| 185 | + ++right; |
| 186 | + } |
| 187 | + return res == n + 1 ? 0 : res; |
| 188 | + } |
| 189 | +} |
76 | 190 | ```
|
77 | 191 |
|
78 | 192 | ### **...**
|
|
0 commit comments