水果成篮
暴力枚举 :
// 暴力 + 哈希 进行枚举
public static int totalFruit2(int[] fruits) {
int maxCount = 0;
for (int i = 0; i < fruits.length; i++) {
HashMap<Integer, Integer> map = new HashMap<>();
int j = i;
for (; j < fruits.length; j++) {
Integer nowNumber = map.get(fruits[j]);
if (map.size() < 2 || nowNumber != null) {
if (nowNumber != null) {
map.put(fruits[j], nowNumber + 1);
} else {
map.put(fruits[j], 1);
}
} else {
// 此时遇到第三个元素了
maxCount = Math.max(j - i, maxCount);
break;
}
}
if (j == fruits.length) {
maxCount = Math.max(j - i, maxCount);
}
}
return maxCount;
}
滑动窗口:
使用 HashMap:
class Solution {
public int totalFruit(int[] fruits) {
int left = 0;
int right = 0;
int maxCount = 0;
HashMap<Integer, Integer> map = new HashMap<>();
while (right < fruits.length) {
int nowNumber = fruits[right];
// 进窗口
map.put(nowNumber, map.getOrDefault(nowNumber, 0) + 1);
// 出窗口
while (map.size() >= 3) {
Integer leftNowNumber = map.get(fruits[left]);
if (leftNowNumber != null) {
if (leftNowNumber == 1) {
map.remove(fruits[left]);
} else {
map.put(fruits[left], leftNowNumber - 1);
}
}
left++;
}
// 更新结果
maxCount = Math.max(right - left + 1, maxCount);
right++;
}
return maxCount;
}
}
使用数组模拟 HashMap
class Solution {
public int totalFruit(int[] fruits) {
int[] hash = new int[fruits.length + 1];
int left = 0;
int right = 0;
int nowCount = 0;
int maxCount = 0;
while (right < fruits.length) {
// 进窗口
if (hash[fruits[right]] == 0) {
nowCount++;
}
hash[fruits[right]]++;
// 判断
while (nowCount > 2) {
// 出窗口
if (hash[fruits[left]]-- == 1) {
nowCount--;
}
left++;
}
// 更新结果
maxCount = Math.max(maxCount, right - left + 1);
right++;
}
return maxCount;
}
}
python:
class Solution(object):
def totalFruit(self, fruits):
left, right, maxCount, nowCount = 0, 0, 0, 0
hash = [0] * (len(fruits) + 1)
while right < len(fruits):
if hash[fruits[right]] == 0:
nowCount += 1
hash[fruits[right]] += 1
while nowCount > 2:
if hash[fruits[left]] == 1:
nowCount -= 1
hash[fruits[left]] -= 1
left += 1
maxCount = max(right - left + 1, maxCount)
right += 1
return maxCount
异位词
438. 找到字符串中所有字母异位词 - 力扣(LeetCode)
暴力枚举:
// 异位词
public static List<Integer> findAnagrams2(String s, String p) {
int[] cur2 = new int[26];
// 记录 p
for (int i = 0; i < p.length(); i++) {
cur2[p.charAt(i) - 'a']++;
}
List<Integer> list = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
int[] cur1 = new int[26];
boolean sTag = true;
for (int j = i; j < i + p.length() && j < s.length(); j++) {
cur1[s.charAt(j) - 'a']++;
}
// 此时找到了一组进行判断
for (int z = 0; z < 26; z++) {
if (cur1[z] != cur2[z]) {
// 使用 sTag 来表示 找到的 字串是否为 p 的异位词
sTag = false;
break;
}
}
if (sTag) {
// 记录下当前位置
list.add(i);
}
}
return list;
}
固定长度滑动窗口
class Solution {
// 固定长度滑动窗口
public List<Integer> findAnagrams(String s, String p) {
int left = 0;
int right = 0;
List<Integer> response = new ArrayList<>();
int[] cur1 = new int[26];
for (char a : p.toCharArray()) {
cur1[a - 'a']++;
}
int[] cur2 = new int[26];
while (right < s.length()) {
// 进窗口
cur2[s.charAt(right) - 'a']++;
if (right - left + 1 > p.length()) {
// 此时超出-->出窗口
cur2[s.charAt(left++) - 'a']--;
}
// 校验当前 窗口内的元素是否为 p 的异位词
if (right - left + 1 == p.length()) {
if (check(cur1, cur2)) {
response.add(left);
}
}
right++;
}
return response;
}
public boolean check(int[] cur1, int[] cur2) {
for (int i = 0; i < 26; i++) {
if (cur1[i] != cur2[i]) {
return false;
}
}
return true;
}
}
优化:
// 优化 --> 不循环 26 次进行比较遍历
public static List<Integer> findAnagrams(String s, String p) {
int left = 0;
int right = 0;
List<Integer> response = new ArrayList<>();
int[] cur1 = new int[26];
for (char a : p.toCharArray()) {
cur1[a - 'a']++;
}
int[] cur2 = new int[26];
int count = 0;
while (right < s.length()) {
// 进窗口 --> cur1 记录 p cur2 记录 s
cur2[s.charAt(right) - 'a']++;
if (cur2[s.charAt(right) - 'a'] <= cur1[s.charAt(right) - 'a']) {
// 此时满足情况
count++;
}
// 出窗口
if (right - left + 1 > p.length()) {
// 判断是否出掉有效字符
if (cur1[s.charAt(left) - 'a'] >= cur2[s.charAt(left) - 'a']) {
count--;
}
cur2[s.charAt(left) - 'a']--;
left++;
}
// 更新结果
if (count == p.length()) {
response.add(left);
}
right++;
}
return response;
}
python:
class Solution(object):
def findAnagrams(self, s, p):
left, right, count = 0, 0, 0
response = []
cur1, cur2 = [0] * 26, [0] * 26
for a in p:
cur1[ord(a) - 97] += 1
while right < len(s):
# 进窗口
cur2[ord(s[right]) - 97] += 1
if cur2[ord(s[right]) - 97] <= cur1[ord(s[right]) - 97]:
count += 1
# 判断 + 出窗口
if right - left + 1 > len(p):
if cur2[ord(s[left]) - 97] <= cur1[ord(s[left]) - 97]:
count -= 1
cur2[ord(s[left]) - 97] -= 1
left += 1
# 更新结果
if count == len(p):
response.append(left)
right += 1
return response