利用单调性,使用同向双指针,两个指针之间形成一个窗口
暴力解决时发现两个指针不需要回退(没必要回退,一定不会符合结果)也可以解决当前的问题,此时就可以使用滑动窗口
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
public int lengthOfLongestSubstring(String s) {
int[] hash = new int[128];
char[] ch = s.toCharArray();
int ret = 0;
for (int left = 0, right = 0; right < s.length(); right++) {
// 进窗口
hash[ch[right]]++;
while (hash[ch[right]] > 1) {
// 出现重复
//出窗口
hash[ch[left]]--;
left++;
}
ret = Math.max(ret, right - left + 1);
}
return ret;
}
给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。
示例 1:
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。
示例 2:
输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。
其实这道题就是需要我们找到一个最长子串,并且这个字串最多可以包含k个0,我们可以使用一个变量记录当前子串中0的个数,当0的个数超出k个之后,从left指针往后依次出窗口,直到满足条件,right指针接着往后面走
public int longestOnes(int[] nums, int k) {
int ret = 0;
int zCount = 0;
int left = 0, right = 0;
while (right < nums.length) {
if (nums[right] == 0) {
zCount++;
}
while (zCount > k) {
if (nums[left++] == 0) {
zCount--;
}
}
ret = Math.max(ret, right - left+1);
right++;
}
return ret;
}
给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。
示例 1:
输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0 。
示例 2:
输入:nums = [5,6,7,8,9], x = 4
输出:-1
示例 3:
输入:nums = [3,2,20,1,1,3], x = 10
输出:5
解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 104
1 <= x <= 109
class Solution {
public int minOperations(int[] nums, int x) {
int target = 0;
for (int i = 0; i < nums.length; i++) {
target+=nums[i];
}
target -= x;
// 处理边界条件
if (target < 0) return -1;
int sum = 0;
int ret = -1;
for (int left = 0, right = 0; right < nums.length; right++) {
// 加入结果
sum+=nums[right];
// 超出范围
while (sum > target) {
// 出结果集
sum-=nums[left++];
}
// 判断长度,更新结果
if (sum == target) {
ret = Math.max(ret, right - left + 1);
}
}
return ret == -1? ret : nums.length - ret;
}
}