567. 字符串的排列(哈希表 滑动窗口)(Leetcode刷题笔记)
欢迎大家访问我的GitHub博客
https://lunan0320.cn
题目
给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
换句话说,s1 的排列之一是 s2 的 子串 。
示例 1:
输入:s1 = “ab” s2 = “eidbaooo”
输出:true
解释:s2 包含 s1 的排列之一 (“ba”).
示例 2:
输入:s1= “ab” s2 = “eidboaoo”
输出:false
解题代码 C++(核心代码)
解题思路:还是用哈希表做滑动窗口的方法,只不过此处需要注意的是判断窗口收缩的条件。
class Solution {
public:
bool checkInclusion(string s1, string s2) {
//建立两个哈希表
unordered_map<char,int> need,window;
for(char c : s1) need[c]++;
int left = 0, right = 0;
int valid = 0;
//遍历一次
while(right < s2.size()){
char c = s2[right];
//right右移
right ++;
//如果从是need中的是有效元素
if(need.count(c)){
window[c]++;
if(window[c] == need[c]){
valid++;
}
}
//判断窗口需要收缩的条件
while(right - left + 1 > s1.size()){
if(valid == need.size()) return true;
char d = s2[left];
left ++;
if(need.count(d)){
if(window[d] == need[d]) valid--;
window[d]--;
}
}
}
return false;
}
};
解题代码 C++(本地编译运行)
//head.h
#include<iostream>
#include <string>
#include <unordered_map>
using namespace std;
//myWindow2.h
#include "head.h"
class myWindow2 {
public:
bool checkInclusion(string s1, string s2) {
unordered_map<char, int> need, window;
for (char c : s1) need[c]++;
int left = 0, right = 0;
int valid = 0;
while (right < s2.size()) {
char c = s2[right];
right++;
if (need.count(c)) {
window[c]++;
if (need[c] == window[c]) valid++;
}
//收缩左边界
while (right - left + 1 > s1.size()) {
char d = s2[left];
left++;
if (valid == need.size()) {
return true;
}
if (need.count(d)) {
if (need[d] == window[d]) valid--;
window[d]--;
}
}
}
return false;
}
};
// main.cpp
#include "myWindow2.h"
int main() {
string s1 = "ab";
string s2 = "eidbaooo";
myWindow2 solution;
cout << solution.checkInclusion(s1, s2) << endl;
return 0;
}
算法效率
执行用时:20 ms, 在所有 C++ 提交中击败了18.55%的用户
内存消耗:7.2 MB, 在所有 C++ 提交中击败了52.98%的用户