北京如何优化网站seo引擎优化平台培训
文章目录
- 题目解析
- 解法⼀(暴⼒求解)(会超时):
- 解法⼆(滑动窗⼝):
- 附Java代码
力扣题目:无重复字符的最长子串
题目解析
解法⼀(暴⼒求解)(会超时):
算法思路:
「从前往后」枚举数组中的任意⼀个元素,把它当成起始位置。然后从这个「起始位置」开始,然
后寻找⼀段最短的区间,使得这段区间的和「⼤于等于」⽬标值。
将所有元素作为起始位置所得的结果中,找到「最⼩值」即可。
class Solution {public:int minSubArrayLen(int target, vector<int>& nums) {int ret = INT_MAX;int n = nums.size();for (int start = 0; start < n; start++){int sum = 0; for (int end = start; end < n; end++){sum += nums[end]; if (sum >= target) ret = min(ret, end - start + 1);break;}}}return ret == INT_MAX ? 0 : ret;}};
解法⼆(滑动窗⼝):
算法思路:
在方法一和方法二中,都是每次确定子数组的开始下标,然后得到长度最小的子数组,因此时间复杂度较高。为了降低时间复杂度,可以使用滑动窗口的方法。
定义两个指针 start 和 end 分别表示子数组(滑动窗口窗口)的开始位置和结束位置,维护变量 sum 存储子数组中的元素和(即从 nums[start] 到 nums[end] 的元素和)。
初始状态下,start 和 end 都指向下标 0,sum 的值为 0。
每一轮迭代,将 nums[end] 加到 sum,如果 sum≥s,则更新子数组的最小长度(此时子数组的长度是 end−start+1),然后将 nums[start] 从 sum 中减去并将 start 右移,直到 sum<s,在此过程中同样更新子数组的最小长度。在每一轮迭代的最后,将 end 右移。
class Solution {
public:int minSubArrayLen(int s, vector<int>& nums) {int n = nums.size();if (n == 0) {return 0;}int ans = INT_MAX;int start = 0, end = 0;int sum = 0;while (end < n) {sum += nums[end];while (sum >= s) {ans = min(ans, end - start + 1);sum -= nums[start];start++;}end++;}return ans == INT_MAX ? 0 : ans;}
};
附Java代码
class Solution {public int minSubArrayLen(int s, int[] nums) {int n = nums.length;if (n == 0) {return 0;}int ans = Integer.MAX_VALUE;int start = 0, end = 0;int sum = 0;while (end < n) {sum += nums[end];while (sum >= s) {ans = Math.min(ans, end - start + 1);sum -= nums[start];start++;}end++;}return ans == Integer.MAX_VALUE ? 0 : ans;}
}