LeetCode题解-03(栈、队列、双指针、哈希表)
目录
- LeetCode题解
- chap-7: 栈、队列
- chap-8:双指针
- chap-9:哈希表
- 1、字母异位词分组
- 2、最长连续序列
- 3、存在重复元素
- 4、存在重复元素 II
- 5、存在重复元素 III
- 6、猜数字游戏
- 7、两个数组的交集
- 8、两个数组的交集 II
- 9、O(1) 时间插入、删除和获取随机元素
- 10、O(1) 时间插入、删除和获取随机元素 - 允许重复
- 11、赎金信
- 12、字符串中的第一个唯一字符
- 13、最长回文串
- 14、路径总和 III
- 15、四数相加 II
- 16、和为 K 的子数组【×】
- 17、LRU 缓存机制【×】
- 18、LFU 缓存
- 19、连续的子数组和【×】前缀和+哈希表
- 20、连续数组【×】
- 21、数组中的 k-diff 数对
- 22、砖墙【×】
- 23、分糖果
- 24、设计哈希映射【×】
- 25、设计哈希集合
- 26、数的平方等于两数乘积的方法数
- 27、警告一小时内使用相同员工卡大于等于三次的人
- 28、字符频次唯一的最小删除次数
- 29、K 和数对的最大数目
- 30、同构字符串【双射】
- 31、单词规律
LeetCode题解
chap-7: 栈、队列
1、最小栈【设计】
class MinStack {
public:
stack<int> a,b;
/** initialize your data structure here. */
MinStack() {
}
void push(int val) {
a.push(val);
if(b.empty() || val <= b.top()) b.push(val);
}
void pop() {
auto t = a.top();
if(b.size() && b.top() == t) b.pop();
a.pop();
}
int top() {
return a.top();
}
int getMin() {
return b.top();
}
};
2、比较含退格的字符串
class Solution {
public:
bool backspaceCompare(string s, string t) {
stack<char>a,b;
for(auto c:s){
if(c == '#'){
if(a.empty()) continue;
else a.pop();
}else a.push(c);
}
for(auto c:t){
if(c == '#'){
if(b.empty()) continue;
else b.pop();
}else b.push(c);
}
if(a.size() != b.size()) return false;
while(a.size()){
if(a.top() != b.top()) return false;
a.pop(), b.pop();
}
return true;
}
};
// 进一步地
class Solution {
public:
string get(string& s) {
string res;
for (auto c: s)
if (c == '#') {
if (res.size()) res.pop_back();
} else {
res += c;
}
return res;
}
bool backspaceCompare(string s, string t) {
return get(s) == get(t);
}
};
3、设计一个支持增量操作的栈 【×】
// inc部分O(k)-O(1)
class CustomStack {
public:
vecto1r<int> inc_arr;
stack<int> st;
int m_size,cnt = 0;
CustomStack(int maxSize) {
m_size = maxSize;
inc_arr.resize(maxSize + 1,0);
}
void push(int x) {
if(cnt < m_size){
cnt ++;
st.push(x);
}
}
int pop() {
if(cnt == 0)
return -1;
int p = st.top();
st.pop();
if(inc_arr[cnt] != 0){
inc_arr[cnt - 1] += inc_arr[cnt];
p += inc_arr[cnt];
inc_arr[cnt] = 0;
}
cnt --;
return p;
}
void increment(int k, int val) {
inc_arr[min(k,cnt)] += val;
}
};
4、设计循环队列
class MyCircularQueue {
public:
int hh = 0, tt = 0;
vector<int> q;
/** Initialize your data structure here. Set the size of the queue to be k. */
MyCircularQueue(int k) {
q.resize(k + 1);
}
/** Insert an element into the circular queue. Return true if the operation is successful. */
bool enQueue(int value) {
if (isFull()) return false;
q[tt ++ ] = value;
if (tt == q.size()) tt = 0;
return true;
}
/** Delete an element from the circular queue. Return true if the operation is successful. */
bool deQueue() {
if (isEmpty()) return false;
hh ++ ;
if (hh == q.size()) hh = 0;
return true;
}
/** Get the front item from the queue. */
int Front() {
if (isEmpty()) return -1;
return q[hh];
}
/** Get the last item from the queue. */
int Rear() {
if (isEmpty()) return -1;
int t = tt - 1;
if (t < 0) t += q.size();
return q[t];
}
/** Checks whether the circular queue is empty or not. */
bool isEmpty() {
return hh == tt;
}
/** Checks whether the circular queue is full or not. */
bool isFull() {
return (tt + 1) % q.size() == hh;
}
};
5、设计循环双端队列
class MyCircularDeque {
public:
int hh = 0, tt = 0;
vector<int> q;
/** Initialize your data structure here. Set the size of the deque to be k. */
MyCircularDeque(int k) {
q.resize(k + 1);
}
int get(int x) {
return (x + q.size()) % q.size();
}
/** Adds an item at the front of Deque. Return true if the operation is successful. */
bool insertFront(int value) {
if (isFull()) return false;
hh = get(hh - 1);
q[hh] = value;
return true;
}
/** Adds an item at the rear of Deque. Return true if the operation is successful. */
bool insertLast(int value) {
if (isFull()) return false;
q[tt ++ ] = value;
tt = get(tt);
return true;
}
/** Deletes an item from the front of Deque. Return true if the operation is successful. */
bool deleteFront() {
if (isEmpty()) return false;
hh = get(hh + 1);
return true;
}
/** Deletes an item from the rear of Deque. Return true if the operation is successful. */
bool deleteLast() {
if (isEmpty()) return false;
tt = get(tt - 1);
return true;
}
/** Get the front item from the deque. */
int getFront() {
if (isEmpty()) return -1;
return q[hh];
}
/** Get the last item from the deque. */
int getRear() {
if (isEmpty()) return -1;
return q[get(tt - 1)];
}
/** Checks whether the circular deque is empty or not. */
bool isEmpty() {
return hh == tt;
}
/** Checks whether the circular deque is full or not. */
bool isFull() {
return get(hh - 1) == tt;
}
};
6、验证栈序列
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> s; int j = 0;
for(int i = 0;i<pushed.size();i++){
if(popped[j] == pushed[i]) {
j++; while(s.size() && s.top() == popped[j]){s.pop(); j++;}
}
else s.push(pushed[i]);
}
while(s.size()){
auto t = s.top(); s.pop();
if(t != popped[j]) return false;
else j++;
}
return true;
}
};
7、删除字符串中的所有相邻重复项
class Solution {
public:
string removeDuplicates(string s) {
string stk;
for(auto &c:s){
if(stk.size() && stk.back() == c) stk.pop_back();
else stk.push_back(c);
}
return stk;
}
};
8、删除字符串中的所有相邻重复项 II
class Solution {
public:
string removeDuplicates(string s, int k) {
string stk("#");
stack<int> cnt;
cnt.push(1);
for(int i = 0 ; i < s.size() ; i++) {
if(s[i] == stk.back()) cnt.push(cnt.top()+1);
else cnt.push(1);
stk += s[i];
if(cnt.top() >= k) {
for(int j = 0 ; j < k ; j++) {
stk.pop_back();
cnt.pop();
}
}
}
return stk.substr(1);
}
};
[Go Back~~](# LeetCode题解)
section7-1: 栈、队列重构
1、用队列实现栈
class MyStack {
public:
/** Initialize your data structure here. */
queue<int> a,b;
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
a.push(x);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
while(a.size() > 1) b.push(a.front()), a.pop();
int t = a.front(); a.pop();
while(b.size()) a.push(b.front()), b.pop();
return t;
}
/** Get the top element. */
int top() {
while(a.size() > 1) b.push(a.front()), a.pop();
int t = a.front(); b.push(a.front()), a.pop();
while(b.size()) a.push(b.front()), b.pop();
return t;
}
/** Returns whether the stack is empty. */
bool empty() {
return a.empty();
}
};
2、用栈实现队列
class MyQueue {
public:
/** Initialize your data structure here. */
stack<int> a,b;
MyQueue() {
}
void in2out(){
while(a.size()) b.push(a.top()), a.pop();
}
/** Push element x to the back of queue. */
void push(int x) {
a.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
if(b.empty()) in2out();
int t = b.top(); b.pop();
return t;
}
/** Get the front element. */
int peek() {
if(b.empty()) in2out();
return b.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return a.empty() && b.empty();
}
};
section7-2: 单调栈
1、接雨水
class Solution {
public:
int trap(vector<int>& h) {
stack<int> help;
int ans = 0;
for(int i=0;i<h.size();i++){
if(help.empty()) help.push(i);
else{
if(h[i] < h[help.top()]) help.push(i);
else{ // h > top()
auto t = help.top(); help.pop();
while(help.size() && h[t] <= h[i]){
auto q = help.top();
if(h[q] <= h[i]) help.pop();
ans += (min(h[q],h[i]) - h[t])*(i-q-1);
t = q;
}
help.push(i);
}
}
}
return ans;
}
};
// 逻辑优化
class Solution {
public:
int trap(vector<int>& h) {
stack<int> help;
int ans = 0;
for(int i=0;i<h.size();i++){
while(!help.empty() && h[help.top()] <= h[i]){
auto t = help.top(); help.pop();
if(help.empty()) break;
ans += (min(h[help.top()],h[i])-h[t])*(i-help.top()-1);
}
help.push(i);
}
return ans;
}
};
2、柱状图中最大的矩形
class Solution {
public:
int largestRectangleArea(vector<int>& h) {
int ans = 0; h.push_back(-1);
stack<int> s;
for(int i=0;i<h.size();i++){
while(s.size() && h[i] < h[s.top()]){
auto t = s.top(); s.pop();
if(s.empty()) ans = max(ans,h[t] * i);
else ans = max(ans,h[t]*(i-s.top()-1));
}
s.push(i);
}
return ans;
}
};
3、最大矩形
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
if(matrix.size() <= 0) return 0;
int ans = 0, m = matrix.size(), n = matrix[0].size();
vector<int>help = vector<int>(n+1,0);
for(int i=0;i<m;i++){
for(int j=0;j<n;j++)
if(matrix[i][j] == '1') help[j]+=1;
else help[j] = 0;
stack<int> s;
for(int j=0;j<=n;j++){
while(s.size() && help[j] < help[s.top()]){
auto t = s.top(); s.pop();
if(s.empty()) ans = max(ans,help[t]*j);
else ans = max(ans,help[t]*(j-s.top()-1));
}
s.push(j);
}
}
return ans;
}
};
4、下一个更大元素 I
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int,int>hash;
stack<int> s;
for(int i=nums2.size()-1;~i;i--){
if(s.empty()) hash[nums2[i]] = -1, s.push(nums2[i]);
else{
while(s.size() && nums2[i] > s.top()){
s.pop();
if(s.empty()) {
hash[nums2[i]] = -1, s.push(nums2[i]);
break;
}
}
if(nums2[i] < s.top()) hash[nums2[i]] = s.top(), s.push(nums2[i]);
}
}
vector<int> ans;
for(auto &num:nums1) ans.push_back(hash[num]);
return ans;
}
};
5、下一个更大元素 II【破环成链】
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n = nums.size();
vector<int> ans(n,0);
nums.insert(nums.end(),nums.begin(),nums.end());
stack<int> s;
for(int i = 2*n-1;~i;i--){
int x = nums[i];
while(s.size() && x >= s.top()) s.pop();
if(i<n){
if(s.empty()) ans[i] = -1;
else ans[i] = s.top();
}
s.push(x);
}
return ans;
}
};
6、每日温度
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& t) {
stack<int> s; int n = t.size();
vector<int> ans(n);
for(int i=n-1;~i;i--){
while(s.size() && t[i] >= t[s.top()]) s.pop();
if(s.empty()){
ans[i] = 0;
}else ans[i] = s.top()-i;
s.push(i);
}
return ans;
}
};
[Go Back~~](# LeetCode题解)
section7-3: 单调队列
1、滑动窗口最大值
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> q;
vector<int> ans;
for(int i = 0;i<nums.size();i++){
if (q.size() && i - k + 1 > q.front()) q.pop_front();
while(q.size() && nums[q.back()] <= nums[i]) q.pop_back();
q.push_back(i);
if(i>=k-1) ans.push_back(nums[q.front()]);
}
return ans;
}
};
section7-4:逆波兰表达式/计算器
1、逆波兰表达式求值
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> s;
for(auto &t:tokens){
if(t == "+" || t == "-" || t == "*" || t == "/"){
int a = s.top(); s.pop();
int b = s.top(); s.pop();
if(t == "+") s.push(b+a);
if(t == "-") s.push(b-a);
if(t == "*") s.push(b*a);
if(t == "/") s.push(b/a);
}else{
s.push(stoi(t));
}
}
return s.top();
}
};
2、基本计算器【×】
class Solution {
public:
void eval(stack<int>& num,stack<char>& op)
{
auto b=num.top();num.pop();
auto a=num.top();num.pop();
auto c=op.top();op.pop();
if(c=='+') num.push(a+b);
else num.push(a-b);
}
int calculate(string rs) {
string s;
for(auto c:rs)
if(c!=' ')
s+=c;
stack<int> num;
stack<char> op;
for(int i=0;i<s.size();i++)
{
auto c=s[i];
if(isdigit(c))
{
int x=0,j=i;
while(j<s.size() && isdigit(s[j])) x=x*10+(s[j++]-'0');
i=j-1;
num.push(x);
}
else if(c=='(') op.push(c);
else if(c==')')
{
while(op.top()!='(') eval(num,op);
op.pop();
}
else
{
if(!i || s[i-1]=='(' || s[i-1]=='+' || s[i-1]=='-')
num.push(0);
while(op.size() && op.top()!='(') eval(num,op);
op.push(c);
}
}
while(op.size()) eval(num,op);
return num.top();
}
};
3、基本计算器 II
class Solution {
public:
int calculate(string s) {
char pre = '+';
vector<int> help;
for(int i = 0;i<s.size();i++){
if(s[i] == ' ') continue;
if(isdigit(s[i])){
int j = i;
while(j<s.size() && isdigit(s[j])) j++;
int t = stoi(s.substr(i,j-i)); i = j-1;
switch (pre){`
case '+':help.push_back(t); break;
case '-':help.push_back(-t); break;
case '*':help.back() = (help.back() * t); break;
default:help.back() = (help.back()/t);
}
}else{
pre = s[i];
}
}
return accumulate(help.begin(),help.end(),0);
}
};
section7-5:括号序列
1、有效的括号
class Solution {
public:
bool isValid(string s) {
stack<char> stk;
for(auto c:s){
if(c == '(' || c == '[' || c == '{') stk.push(c);
else{
if(stk.size()){
auto t = stk.top();
if(c-t==')'-'(' || c-t==']'-'[' || c-t=='}'-'{')
stk.pop();
else return false;
} else return false;
}
}
return stk.empty();
}
};
2、最长有效括号
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> stk; // 记录左括号位置
int start = 0, ans = 0;
for(int i = 0;i<s.size();i++){
if(s[i] == '(') stk.push(i);
else{
if(stk.empty()) start = i+1;
else{
stk.pop();
if(stk.empty()) ans = max(i-start+1,ans);
else ans = max(i-stk.top(),ans);
}
}
}
return ans;
}
};
[Go Back~~](# LeetCode题解)
chap-8:双指针
section8.1 同向双指针
1、外观数列【模拟】
class Solution {
public:
string countAndSay(int n) {
string ans = "1";
while(--n){
string temp;
for(int i = 0;i<ans.size();i++){
int j = i+1,cnt=1;
while(j<ans.size() && ans[j] == ans[i]) cnt++,j++;
temp += to_string(cnt) + ans[i];
i = j-1;
}
ans = temp;
}
return ans;
}
};
2、最后一个单词的长度
class Solution {
public:
int lengthOfLastWord(string s) {
int n = s.length() - 1;
while(n >=0 && s[n] == ' ') n--;
int i = n;
while(~i && s[i] != ' ') i--;
return i>=0 ? n-i:n+1;
}
};
3、删除有序数组中的重复项
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.empty()) return 0;
int j=0;
for(int i=j+1;i<nums.size();i++){
if(nums[j] == nums[i])continue;
else nums[++j] = nums[i];
}
return j+1;
}
};
4、删除有序数组中的重复项 II
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.empty()) return 0;
int j=0;
for(int i = j+1;i<nums.size();i++){
if(nums[j] == nums[i]){
if(j && nums[j-1] == nums[j]) continue;
else nums[++j] = nums[i];
}else
nums[++j] = nums[i];
}
return j+1;
}
};
5、移除元素
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
if(nums.empty()) return 0;
int len = 0;
for(int i=len;i<nums.size();i++){
if(nums[i] == val) continue;
else {
nums[len++] = nums[i];
}
}
return len;
}
};
6、颜色分类
class Solution {
public:
void sortColors(vector<int>& nums) {
int l=-1,r=nums.size();
for(int i=0;i<r;){
if(nums[i] == 0){
swap(nums[++l],nums[i]);
i = l+1;
}else if(nums[i] == 2){
swap(nums[--r],nums[i]);
}else i++;
}
}
};
7、合并两个有序数组
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int i = m-1, j = n-1, k = m+n-1;
while(~i && ~j){
if(nums1[i] > nums2[j]) nums1[k--] = nums1[i--];
else nums1[k--] = nums2[j--];
}
while(~i) nums1[k--] = nums1[i--];
while(~j) nums1[k--] = nums2[j--];
}
};
8、移动零
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int i = 0;
while(i<nums.size() && nums[i])i++;
for(int j = i+1;j<nums.size();j++){
if(nums[j] == 0)continue;
else swap(nums[i++],nums[j]);
}
}
};
9、判断子序列
class Solution { // 双指针
public:
bool isSubsequence(string t, string s) {
int i = 0, j = 0;
while(i<s.size() && j<t.size()){
if(s[i] == t[j]) i++,j++;
else i++;
}
return j==t.size();
}
};
// 进阶问题处理思路
class Solution {
public:
bool isSubsequence(string s, string t) {
int n = s.size(), m = t.size();
vector<vector<int>> f(m+1, vector<int>(26,0));
for(int i = 0;i<26;i++) f[m][i] = m;
for(int i = m-1;i>=0;i--){
for(int j = 0;j<26;j++){
if(j == t[i]-'a') f[i][j] = i;
else f[i][j] = f[i+1][j];
}
}
int idx = 0; // f起始处开始搜
for (int i = 0; i < n; i++) {
if (f[idx][s[i] - 'a'] == m) {
return false;
}
idx = f[idx][s[i] - 'a'] + 1; // 下一个位置
}
return true;
}
};
10、字符串中的单词数
// 库函数
class Solution {
public:
int countSegments(string s) {
stringstream sin(s);
int ans = 0; string c;
while(sin>>c) ans++;
return ans;
}
};
// 双指针
class Solution {
public:
int countSegments(string s) {
int res = 0;
for(int i = 0;i<s.size();i++){
if(s[i] == ' ')continue;
int j = i+1;
while(j<s.size() && s[j] != ' ')j++;
res++; i = j-1;
}
return res;
}
};
11、压缩字符串
class Solution {
public:
int compress(vector<char>& chars) {
int ans = 0;
for(int i = 0;i<chars.size();i++){
int j = i+1, t = 1;
while(j<chars.size() && chars[j] == chars[i]) j++, t++;
chars[ans++] = chars[i];
if(t > 1) {
i = j-1;
string s = to_string(t);
for(j=0;j<s.size();j++) chars[ans++] = s[j];
}
}
return ans;
}
};
12、最大连续 1 的个数
class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int ans = 0;
for(int i=0;i<nums.size();i++){
if(nums[i] == 0)continue;
else{
int j = i+1;
while(j<nums.size() && nums[j] == 1) j++;
ans = max(ans,j-i);
i = j-1;
}
}
return ans;
}
};
13、划分字母区间[×]
class Solution {
public:
vector<int> partitionLabels(string s) {
unordered_map<int,int> hash;
int i = 0,start = 0,end = 0;
vector<int> ans;
for(;i<s.size();i++)hash[s[i]] = i;
for(i = 0;i<s.size();i++){
end = max(end,hash[s[i]]);
if(i == end){
ans.push_back(end - start + 1);
start = end = i+1;
}
}
return ans;
}
};
14、按奇偶排序数组 II
class Solution {
public:
vector<int> sortArrayByParityII(vector<int>& nums) {
int slow = 0, fast = slow+1;
while(true){
while(slow < nums.size() && nums[slow]%2 == 0) slow+=2;
while(fast < nums.size() && nums[fast]%2) fast+=2;
if(fast >= nums.size()) break;
else{
swap(nums[slow],nums[fast]);
}
}
return nums;
}
};
15、区间列表的交集
class Solution {
public:
vector<vector<int>> intervalIntersection(vector<vector<int>>& f, vector<vector<int>>& s) {
vector<vector<int>> ans;
for(int i = 0,j = 0;i<f.size() && j<s.size();){
if(f[i][0] <= s[j][1] && f[i][1] >= s[j][0])
ans.push_back({max(f[i][0],s[j][0]),min(f[i][1],s[j][1])});
if(f[i][1] <= s[j][1]) i++;
else j++;
}
return ans;
}
};
[Go Back~~](# LeetCode题解)
section8.2 滑动窗口
1、无重复字符的最长子串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int ans = 0;
unordered_map<char,int> hash;
for(int last = 0, cur = 0;cur < s.size();cur++){
hash[s[cur]]++;
while(hash[s[cur]] == 2){
hash[s[last++]]--;
}
ans = max(ans,cur-last+1);
}
return ans;
}
};
2、最小覆盖子串
class Solution {
public:
string minWindow(string s, string t) {
string ans = "";
unordered_map<char,int> hash;
int cnt = 0;
for(auto c:t) {
if(!hash[c]) cnt++;
hash[c]++;
}
for(int i=0,j=0,c=0;i<s.size();i++){
if(hash[s[i]] == 1) c++;
hash[s[i]]--;
while(c == cnt && hash[s[j]] < 0) hash[s[j++]]++;
if(c == cnt) {
if(ans.empty() || ans.size() > i-j+1) ans = s.substr(j,i-j+1);
}
}
return ans;
}
};
3、长度最小的子数组
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int ans = 0;
for(int i=0,j=0,t=0;i<nums.size();i++){
t+=nums[i];
while(t >= target) {
ans = ans == 0?i-j+1: min(ans,i-j+1);
t-=nums[j++];
if(t >= target) ans = ans == 0?i-j+1: min(ans,i-j+1);
}
}
return ans;
}
};
4、替换后的最长重复字符
class Solution {
public:
int characterReplacement(string s, int k) {
int ans = 0;
for (char c='A'; c<='Z'; c++){
for(int i=0,j=0,cnt=0;i<s.size();i++){
if(s[i] == c) cnt++;
while(i-j+1 - cnt > k){
if(s[j] == c) cnt--;
j++;
}
ans = max(ans, i-j+1);
}
}
return ans;
}
};
5、找到字符串中所有字母异位词
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
int m=s.size(),n=p.size();
vector<int> res;
if(n>m) return res;
unordered_map<char,int> hash;
for(auto&c:p)hash[c]++;
int tot = hash.size();
for(int i=0,j=0,k=0;i<s.size();i++){
if(--hash[s[i]] == 0) k++;
if(i - j + 1 > p.size()){
if(hash[s[j]] == 0) k--;
hash[s[j++]]++;
}
if(k == tot) res.push_back(j);
}
return res;
}
};
6、数组中的 k-diff 数对
// O(n)
class Solution {
public:
int findPairs(vector<int>& nums, int k) {
if(k<0) return 0;
unordered_set<int> first_ele, hash;
for(int i=0;i<nums.size();i++){
if(hash.find(nums[i] - k) != hash.end()) first_ele.insert(nums[i]-k);
if(hash.find(nums[i] + k) != hash.end()) first_ele.insert(nums[i]);
hash.insert(nums[i]);
}
return first_ele.size();
}
};
// O(nlogn)
class Solution {
public:
int findPairs(vector<int>& nums, int k) {
int ans = 0;
sort(nums.begin(), nums.end());
for(int i=0,j=0;i<nums.size();i++){
while(i+1<nums.size() && nums[i+1] == nums[i]) i++;
while(j < i && nums[i] - nums[j] > k) j++;
if(j < i && nums[i] - nums[j] == k) ans++;
}
return ans;
}
};
7、字符串的排列
class Solution {
public:
bool checkInclusion(string s1, string s) {
unordered_map<char,int> hash;
for(auto c:s1) hash[c]++;
int tot = hash.size();
for(int i=0, j=0, cnt = 0; i<s.size(); i++){
if(--hash[s[i]] == 0) cnt++;
if(i-j+1 > s1.size()){
if(hash[s[j]] == 0) cnt--;
hash[s[j++]]++;
}
if(cnt == tot) return true;
}
return false;
}
};
8、最大连续1的个数 III
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int ans=0;
for(int i=0,j=0,cnt=0;i<nums.size();i++){
if(nums[i] == 1) cnt++;
if(i-j+1 - cnt <= k) ans = max(ans, i-j+1);
while(i-j+1 - cnt > k){
if(nums[j++] == 1) cnt--;
}
}
return ans;
}
};
9、删掉一个元素以后全为 1 的最长子数组
class Solution {
public:
int longestSubarray(vector<int>& nums) {
int res = 0;
for(int l = 0 ,r = 0, cnt = 0;r<nums.size();r++){
if(nums[r]==0){
cnt++;
}
while(cnt>1){
if(nums[l]==0){
cnt--;
}
l++;
}
res = max(res,r-l+1);
}
return res-1;
}
};
10、删除子数组的最大得分
class Solution {
public:
int maximumUniqueSubarray(vector<int>& nums) {
int ans = 0;
unordered_map<int,int> hash;
for(int i=0,j=0,tot=0;i<nums.size();i++){
hash[nums[i]]++;
tot+=nums[i];
while(hash[nums[i]] != 1){
hash[nums[j]]--;
tot-=nums[j];
j++;
}
ans = max(ans,tot);
}
return ans;
}
};
[Go Back~~](# LeetCode题解)
section8.3 逆向双指针
1、最长回文子串
class Solution {
public:
string longestPalindrome(string s) {
vector<int> t = {0,0};
for(int i = 0;i<s.size();i++){
int l = i,r = i;
while(l >= 0 && r < s.size() && s[l] == s[r]){
if(t[1] - t[0] < (r-l+1)){
t[0] = l; t[1] = r;
}
l--; r++;
}
l = i-1;r = i;
while(l >= 0 && r < s.size() && s[l] == s[r]){
if(t[1] - t[0] < (r-l+1)){
t[0] = l; t[1] = r;
}
l--; r++;
}
}
return s.substr(t[0],t[1] - t[0] + 1);
}
};
2、盛最多水的容器
class Solution {
public:
int maxArea(vector<int>& height) {
int l = 0, r = height.size()-1, res = 0;
while(l<r){
res = max(res, min(height[r] , height[l]) * (r - l));
if(height[l] < height[r]) l++;
else r--;
}
return res;
}
};
3、三数之和
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
if(nums.size() < 3) return res;
sort(nums.begin(),nums.end());
for(int i = 0;i<nums.size();i++){
if(i && nums[i] == nums[i-1]) continue;
for(int j = i+1,k = nums.size()-1;j<k;){
if(j != i+1 && nums[j] == nums[j-1]) j++;
else{
if(nums[j] + nums[k] < 0 - nums[i]) j++;
else if(nums[j] + nums[k] > 0 - nums[i]) k--;
else {
res.push_back({nums[i],nums[j],nums[k]});
j++;
}
}
}
}
return res;
}
};
4、最接近的三数之和
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
pair<int,int> pii(INT_MAX,INT_MAX);
sort(nums.begin(),nums.end());
for(int i = 0;i<nums.size()-2;i++){
for(int j = i+1,k=nums.size()-1;j<k;){
int t = nums[j] + nums[k] + nums[i];
if(t < target){
j++;
pii = min(pii,make_pair(abs(target - t),t));
}else if(t > target){
k--;
pii = min(pii,make_pair(abs(target - t),t));
}else return target;
}
}
return pii.second;
}
};
5、四数之和
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
if(nums.size() < 4) return res;
sort(nums.begin(),nums.end());
for(int i = 0;i<nums.size();i++){
if(i != 0 && nums[i-1] == nums[i]) continue;
for(auto j = i+1;j<nums.size();j++){
if(j != i+1 && nums[j-1] == nums[j]) continue;
int l = j+1, r = nums.size()-1;
while(l<r){
long long sum = nums[i];
sum += nums[j];
sum += nums[l];
sum += nums[r];
if(sum == target){
res.push_back({nums[i] ,nums[j] ,nums[l] ,nums[r]});
do{l ++;} while(l < r && nums[l] == nums[l - 1]);
do{r --;} while(l < r && nums[r] == nums[r + 1]);
}else if(sum < target) l++; else r--;
}
}
}
return res;
}
};
6、验证回文串
class Solution {
public:
bool isPalindrome(string s) {
int l = 0, r = s.size()-1;
while(l<r){
if(!isalnum(s[l]) && !isalpha(s[l])) {l++; continue; }
if(!isalnum(s[r]) && !isalpha(s[r])) {r--; continue; }
if(s[l] == s[r] || (abs(s[l] - s[r]) == 'a'-'A') && isalpha(s[l]) && isalpha(s[r])){
l++,r--;
}else return false;
}
return true;
}
};
7、两数之和 II - 输入有序数组
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
for(int i = 0,j = numbers.size()-1;i<j;){
if(numbers[i] + numbers[j] > target) j--;
if(numbers[i] + numbers[j] < target) i++;
if(numbers[i] + numbers[j] == target) return{i+1,j+1};
}
return {-1,-1};
}
};
8、反转字符串
class Solution {
public:
void reverseString(vector<char>& s) {
for(int l = 0, r = s.size()-1;l<r;){
swap(s[l],s[r]);
l++;
r--;
}
}
};
9、反转字符串中的元音字母
class Solution {
public:
bool is(char c) {
if(c=='a' || c=='e' || c=='i' || c=='o' || c=='u' ||
c=='A' || c=='E' || c=='I' || c=='O' || c=='U' )
return true;
else return false;
}
string reverseVowels(string s) {
string ans = s;
for(int l=0,r=s.size()-1;l<r;){
while(l<r && !is(ans[l])) l++;
while(r>l && !is(ans[r])) r--;
swap(ans[l], ans[r]);
l++; r--;
}
return ans;
}
};
[Go Back~~](# LeetCode题解)
chap-9:哈希表
1、字母异位词分组
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string,vector<string>> hash;
for(auto &str:strs){
string s = str;
sort(s.begin(),s.end());
if(hash.find(s) != hash.end()){
hash[s].emplace_back(str);
}else{
hash[s] = vector<string>({str});
}
}
vector<vector<string>> ans;
for(auto &iter:hash){
ans.emplace_back(iter.second);
}
return ans;
}
};
2、最长连续序列
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> s(nums.begin(),nums.end());
int ans = 0;
for(auto& num:s){
if(s.find(num - 1) == s.end()){
int st = num;
while(s.find(++st) != s.end());
ans = max(st - num,ans);
}
}
return ans;
}
};
// 法2
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_map<int,int> right,left;
int ans = 0;
for(auto &num:nums){
int l = right[num-1]; // right:表示以x为右终点
int r = left[num+1]; // left:表示以x为左起点
right[num+r] = max(right[num+r], l+r+1);
left[num-l] = max(left[num-l], l+r+1);
ans = max(ans, l+r+1);
}
return ans;
}
};
3、存在重复元素
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_set<int> v;
for (int i = 0; i < nums.size(); i++) {
if (v.find(nums[i]) != v.end())
return true;
v.insert(nums[i]);
}
return false;
}
};
4、存在重复元素 II
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
unordered_map<int,int> hash;
for(int i=0;i<nums.size();i++){
if(hash.find(nums[i]) != hash.end()){
if(i - hash[nums[i]] <= k) return true;
else hash[nums[i]] = i;
}else hash[nums[i]] = i;
}
return false;
}
};
5、存在重复元素 III
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
typedef long long ll;
multiset<ll> hash;
hash.insert(1e18); hash.insert(-1e18);
for(int i=0,j=0;i<nums.size();i++){
if(i-j > k){
hash.erase(hash.find(nums[j++]));
}
int x = nums[i];
auto it = hash.lower_bound(x);
if(*it - x <= t) return true;
it--;
if(x - *it <= t) return true;
hash.insert(x);
}
return false;
}
};
6、猜数字游戏
class Solution {
public:
string getHint(string secret, string guess) {
unordered_map<char,int> hash;
for(auto c:secret) hash[c]++;
int tot=0, bulls=0;
for(int i=0;i<guess.size();i++){
if(secret[i] == guess[i]) bulls++;
if(hash[guess[i]]){
tot++;
hash[guess[i]]--;
}
}
return to_string(bulls)+"A"+to_string(tot-bulls)+"B";
}
};
7、两个数组的交集
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> n1(nums1.begin(), nums1.end());
vector<int> ans;
for(auto x:nums2){
if(n1.count(x)) {
ans.push_back(x);
n1.erase(x);
}
}
return ans;
}
};
8、两个数组的交集 II
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
unordered_multiset<int> S;
vector<int> res;
for (int x : nums1) S.insert(x);
for (int x : nums2)
if (S.count(x))
{
res.push_back(x);
S.erase(S.find(x));
}
return res;
}
};
9、O(1) 时间插入、删除和获取随机元素
class RandomizedSet {
public:
vector<int> temp;
unordered_map<int,int> hash;
int cnt = 0;
RandomizedSet() {
}
bool insert(int val) {
if(hash.find(val) == hash.end()){
hash[val] = cnt++;
temp.push_back(val);
return true;
}
else return false;
}
bool remove(int val) {
auto it = hash.find(val);
if(it != hash.end()){
int idx = it->second;
temp[idx] = temp.back();
hash[temp[idx]] = idx;
temp.pop_back();
cnt--;
hash.erase(it);
return true;
}else return false;
}
int getRandom() {
return temp[rand()%cnt];
}
};
10、O(1) 时间插入、删除和获取随机元素 - 允许重复
class RandomizedCollection {
public:
vector<int> num;
unordered_map<int,unordered_set<int>> hash;
RandomizedCollection() {
}
bool insert(int val) {
bool f = hash.find(val) == hash.end();
num.push_back(val);
hash[val].insert(num.size()-1);
return f;
}
bool remove(int val) {
if(hash.find(val) != hash.end()){
if(num.back() == val){
hash[val].erase(hash[val].find(num.size()-1));
num.pop_back();
if (hash[val].empty())
hash.erase(val);
return true;
}
int t = *hash[val].begin();
hash[num.back()].erase(num.size() - 1);
hash[num.back()].insert(t);
swap(num[t], num.back());
num.pop_back();
hash[val].erase(t);
if (hash[val].empty())
hash.erase(val);
return true;
}
return false;
}
int getRandom() {
return num[rand() % num.size()];
}
};
11、赎金信
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
if(magazine.size() < ransomNote.size()) return false;
unordered_map<char,int> hash;
for(auto c:magazine) hash[c]++;
for(auto c:ransomNote){
if(hash[c] == 0) return false;
else hash[c]--;
}
return true;
}
};
12、字符串中的第一个唯一字符
class Solution {
public:
int firstUniqChar(string s) {
unordered_map<char,int> hash;
for(auto c:s) hash[c]++;
for(int i=0;i<s.size();i++)
if(hash[s[i]] == 1) return i;
return -1;
}
};
13、最长回文串
class Solution {
public:
int longestPalindrome(string s) {
unordered_map<char,int> hash;
for(auto c:s) hash[c]++;
int ans = 0;
bool f = false;
for(auto &it:hash){
if(it.second % 2){
if(!f) f = true;
ans+=it.second-1;
}else ans+=it.second;
}
if(f) return ans+1;
else return ans;
}
};
14、路径总和 III
class Solution {
public:
int res = 0;
unordered_map<int,int> cnt;
int pathSum(TreeNode* root, int t) {
cnt[0] = 1;
dfs(root,t,0);
return res;
}
void dfs(TreeNode*root,int t,int cur_sum){
if(root == nullptr) return;
cur_sum += root->val;
res += cnt[cur_sum - t];
cnt[cur_sum]++;
dfs(root->left,t,cur_sum);
dfs(root->right,t,cur_sum);
cnt[cur_sum]--;
}
};
15、四数相加 II
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> hash;
for(int i=0;i<nums1.size();i++){
for(int j=0;j<nums1.size();j++)
hash[nums1[i]+nums2[j]]++;
}
int ans = 0;
for(int i=0;i<nums1.size();i++){
for(int j=0;j<nums1.size();j++){
if(hash.find(-nums3[i]-nums4[j]) != hash.end())
ans+=hash[-nums3[i]-nums4[j]];
}
}
return ans;
}
};
16、和为 K 的子数组【×】
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int ans=0,tot=0;
unordered_map<int,int> hash;
hash[0]=1;
for(auto &x:nums){
tot+=x;
ans+=hash[tot-k];
hash[tot]++;
}
return ans;
}
};
//通俗做法-超时O(n2)
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int ans = 0;
for(int i=0;i<nums.size();i++){
int sum = 0;
for(int j=i;j>=0;j--){
sum+=nums[j];
if(sum == k) ans++;
}
}
return ans;
}
};
17、LRU 缓存机制【×】
class LRUCache {
public:
struct Node{
int key, val;
Node* left;
Node* right;
Node(int _key, int _val): key(_key), val(_val), left(nullptr), right(nullptr){}
}*L, *R;
unordered_map<int, Node*> hash;
int n;
void remove(Node *p){
p->left->right = p->right;
p->right->left = p->left;
}
void insert(Node *p){
p->right = L->right;
p->left = L;
L->right->left = p;
L->right = p;
}
LRUCache(int capacity) {
n = capacity;
L = new Node(-1,-1);
R = new Node(-1,-1);
L->right = R;
R->left = L;
}
int get(int key) {
if(hash.find(key) == hash.end()) return -1;
auto p = hash[key];
remove(p); // 先后顺序搞清
insert(p);
return p->val;
}
void put(int key, int value) {
if(hash.find(key)!=hash.end()){
auto p = hash[key];
p->val = value;
remove(p);
insert(p);
}else{
if(hash.size() == n){
auto p = R->left;
remove(p);
hash.erase(p->key);
delete p;
}
auto q = new Node(key, value);
insert(q);
hash[key] = q;
}
}
};
18、LFU 缓存
class LFUCache {
public:
struct Node{
Node *left, *right;
int key, val;
Node(int _key,int _val):key(_key), val(_val), left(NULL), right(NULL){}
};
struct Block{
Block *left,*right;
Node *head,*tail;
int cnt;
~Block(){
delete head;
delete tail;
}
Block(int _cnt){
cnt = _cnt;
left = right = NULL;
head = new Node(-1,-1);
tail = new Node(-1,-1);
head->right = tail, tail->left = head;
}
void insert(Node *p){
p->right = head->right;
head->right->left = p;
p->left = head;
head->right = p;
}
void remove(Node *p){
p->left->right = p->right;
p->right->left = p->left;
}
bool empty(){
return head->right == tail;
}
}*head,*tail;
int n;
unordered_map<int, Block*> hash_block;
unordered_map<int, Node*> hash_node;
void insert(Block *p){ // 在p的右侧插入新块,cnt是p->cnt + 1
auto cur = new Block(p->cnt + 1);
cur->right = p->right;
p->right->left = cur;
p->right = cur;
cur->left = p;
}
void remove(Block* p) {
p->left->right = p->right;
p->right->left = p->left;
delete p;
}
LFUCache(int capacity) {
n = capacity;
head = new Block(0), tail = new Block(INT_MAX);
head->right = tail, tail->left = head;
}
int get(int key) {
if(hash_block.find(key) == hash_block.end()) return -1;
auto block = hash_block[key];
auto node = hash_node[key];
block->remove(node);
if (block->right->cnt != block->cnt + 1) insert(block);
block->right->insert(node);
hash_block[key] = block->right;
if (block->empty()) remove(block);
return node->val;
}
void put(int key, int value) {
if(!n) return; // 特例
if(hash_block.find(key) != hash_block.end()){
hash_node[key]->val = value;
get(key);
}
else{
if (hash_block.size() == n) {
auto p = head->right->tail->left;
head->right->remove(p);
if (head->right->empty()) remove(head->right);
hash_block.erase(p->key);
hash_node.erase(p->key);
delete p;
}
auto p = new Node(key, value);
if (head->right->cnt > 1) insert(head);
head->right->insert(p);
hash_block[key] = head->right;
hash_node[key] = p;
}
}
};
19、连续的子数组和【×】前缀和+哈希表
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
int n = nums.size();
vector<int> s(n+1);
for(int i=1;i<=n;i++) s[i] = s[i-1]+nums[i-1];
unordered_set<int> hash;
for(int i =2;i<=n;i++){
hash.insert(s[i-2]%k);
if(hash.count(s[i]%k)) return true;
}
return false;
}
};
20、连续数组【×】
class Solution {
public:
int findMaxLength(vector<int>& nums) {
int ans = 0;
unordered_map<int,int>hash;
hash[0] = 0;
for(int i=1,x=0;i<=nums.size();i++){
x+=(nums[i-1] == 1?1:-1);
if(hash.count(x)) ans = max(ans,i-hash[x]);
else hash[x]=i;
}
return ans;
}
};
21、数组中的 k-diff 数对
class Solution {
public:
int findPairs(vector<int>& nums, int k) {
unordered_set<int> hash, ele;
for(int i=0;i<nums.size();i++){
if(hash.find(nums[i] + k) != hash.end()) ele.insert(nums[i]);
if(hash.find(nums[i] - k) != hash.end()) ele.insert(nums[i] - k);
hash.insert(nums[i]);
}
return ele.size();
}
};
22、砖墙【×】
class Solution {
public:
int leastBricks(vector<vector<int>>& wall) {
int width = accumulate(wall[0].begin(), wall[0].end(), 0);
unordered_map<int,int> hash;
int sum;
for(auto &a:wall){
sum = 0;
for(auto& b:a)
sum+=b, hash[sum]++;
}
sum=0;
for(auto &it:hash){
if(it.first != width)
sum = max(sum,it.second);
}
return wall.size() - sum;
}
};
23、分糖果
class Solution {
public:
int distributeCandies(vector<int>& candyType) {
unordered_set<int> hash(candyType.begin(), candyType.end());
return min(candyType.size()/2, hash.size());
}
};
24、设计哈希映射【×】
// 开放寻址法
class MyHashMap {
public:
const static int N=20011;
int hash_key[N], hash_val[N];
MyHashMap() {
memset(hash_key,-1,sizeof(hash_key));
}
int find(int key){
int t = key%N;
while(hash_key[t] != key && hash_key[t] != -1)
if(++t == N)
t = 0;
return t;
}
void put(int key, int value) {
int t = find(key);
hash_key[t] = key;
hash_val[t] = value;
}
int get(int key) {
int t = find(key);
if(hash_key[t] == -1) return -1;
return hash_val[t];
}
void remove(int key) {
int t = find(key);
if (hash_key[t] != -1)
hash_key[t] = -2;
}
};
25、设计哈希集合
// 拉链法
class MyHashSet {
public:
const static int N = 20011;
vector<int> help[N];
MyHashSet() {
}
int find(vector<int>&h, int key){
for(int i=0;i<h.size();i++)
if(h[i] == key) return i;
return -1;
}
void add(int key) {
int t = key%N;
int k = find(help[t], key);
if(k == -1) help[t].emplace_back(key);
}
void remove(int key) {
int t = key%N;
int k = find(help[t], key);
if(k != -1){
help[t].erase(help[t].begin()+k);
}
}
bool contains(int key) {
int t = key%N;
return find(help[t], key) != -1;
}
};
26、数的平方等于两数乘积的方法数
class Solution {
public:
int numTriplets(vector<int>& nums1, vector<int>& nums2) {
typedef long long ll;
unordered_map<ll,int> hash;
for(auto num:nums1) hash[(ll)num*num]++;
int ans = 0;
for(int i=0;i<nums2.size();i++){
for(int j=i-1;j>=0;j--){
if(hash.count((ll)nums2[i]*nums2[j]))
ans+=hash[(ll)nums2[i]*nums2[j]];
}
}
unordered_map<ll,int> hash1;
for(auto num:nums2) hash1[(ll)num*num]++;
for(int i=0;i<nums1.size();i++){
for(int j=i-1;j>=0;j--){
if(hash1.count((ll)nums1[i]*nums1[j]))
ans+=hash1[(ll)nums1[i]*nums1[j]];
}
}
return ans;
}
};
27、警告一小时内使用相同员工卡大于等于三次的人
class Solution {
public:
vector<string> alertNames(vector<string>& keyName, vector<string>& keyTime) {
unordered_map<string,vector<int>> hash;
for(int i=0;i<keyName.size();i++){
int hh,mm;
sscanf(keyTime[i].c_str(),"%d:%d",&hh,&mm);
hash[keyName[i]].push_back(hh*60+mm);
}
vector<string> ans;
for(auto &it:hash){
sort(it.second.begin(),it.second.end());
for(int i=2;i<it.second.size();i++){
if(it.second[i] - it.second[i-2] <= 60){
ans.push_back(it.first);
break;
}
}
}
sort(ans.begin(), ans.end());
return ans;
}
};
28、字符频次唯一的最小删除次数
class Solution {
public:
int minDeletions(string s) {
vector<int> help(26);
for(auto c:s) help[c-'a']++;
sort(help.rbegin(), help.rend());
int ans = 0;
for(int i=0;i<help.size()-1;i++){
if(help[i] > help[i+1]) continue;
if(help[i] == 0){
ans += help[i+1];
help[i+1] = 0;
}else{
int a = help[i]-1;
ans += help[i+1] - a;
help[i+1] = a;
}
}
return ans;
}
};
29、K 和数对的最大数目
class Solution {
public:
int maxOperations(vector<int>& nums, int k) {
unordered_map<int,int> hash;
for(auto t:nums) hash[t]++;
int ans = 0;
for(auto &t:hash){
if(hash.find(k - t.first) != hash.end()){
if(k - t.first == t.first) ans += t.second-1;
else ans += min(t.second, hash[k - t.first]);
}
}
return (ans+1)/2; //
}
};
30、同构字符串【双射】
class Solution {
public:
bool isIsomorphic(string s, string t) {
unordered_map<char,char> hashs;
unordered_map<char,char> hasht;
for(auto i=0;i<s.size();i++){
if(hashs.count(t[i]))
if(hashs[t[i]] == s[i]) continue;
else return false;
else hashs[t[i]] = s[i];
if(hasht.count(s[i]))
if(hasht[s[i]] == t[i]) continue;
else return false;
else hasht[s[i]] = t[i];
}
return true;
}
};
31、单词规律
class Solution {
public:
bool wordPattern(string t, string s) {
stringstream sstream(s);
unordered_map<char,string> ts;
unordered_map<string,char> st;
int i = 0;
while(sstream){
string tt;
sstream>>tt;
if(ts.count(t[i])){
if(ts[t[i]] != tt) return false;
}else ts[t[i]] = tt;
if(st.count(tt)){
if(st[tt] != t[i]) return false;
}else st[tt] = t[i];
i++;
}
return i == (t.size()+1);
}
};
[Go Back~~](# LeetCode题解)
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。