哈希 3 题
1 两数之和
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int n = nums.size();
unordered_map<int, int> mp;
for(int i = 0; i < n; i ++ ) {
if(mp[target - nums[i]])
return {i, mp[target - nums[i]] - 1};
mp[nums[i]] = i + 1;
}
return {};
}
};
49 字母异位词分组
Cpp
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> ans;
int n = strs.size();
unordered_map<string, vector<string>> mp;
for(auto str: strs) {
string ss = str;
sort(ss.begin(), ss.end());
mp[ss].push_back(str);
}
for(auto [k, v]: mp) {
ans.push_back(v);
}
return ans;
}
};
128 最长连续序列
Cpp
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
int n = nums.size();
unordered_set<int> st(nums.begin(), nums.end());
int ans = 0;
for(auto num : st) {
if(st.count(num - 1) == 0) {
int l = num, r = num + 1;
while(st.find(r) != st.end()) r ++;
ans = max(ans, r - l);
}
}
return ans;
}
};
双指针 4 题
283 移动零
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int n = nums.size();
int l = 0, r = 0;
while(r < n) {
if(nums[r]) {
swap(nums[l], nums[r]);
l ++;
}
r ++;
}
}
};
11 承最多水的容器
class Solution {
public:
int maxArea(vector<int>& h) {
int n = h.size();
int l = 0, r = n - 1;
int ans = 0;
while(l < r) {
if(l < r && h[l] < h[r]) {
ans = max(ans, h[l] * (r - l));
l ++;
} else if(l < r && h[l] >= h[r]) {
ans = max(ans, h[r] * (r - l));
r --;
}
}
return ans;
}
};
15 三数之和
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
unordered_map<int, int> mp;
vector<vector<int>> ans;
int n = nums.size();
for(int i = 0; i < n; i ++ ) mp[nums[i]] = i;
for(int i = 0; i < n; ) {
for(int j = i + 1; j < n; ) {
int x = nums[i], y = nums[j], z = -nums[i] - nums[j];
if(mp[z] > j) {
ans.push_back({x, y, z});
}
int p = j;
while(p < n && nums[p] == nums[j]) p ++;
j = p;
}
int q = i;
while(q < n && nums[q] == nums[i]) q ++;
i = q;
}
return ans;
}
};
42 接雨水
class Solution {
public:
int trap(vector<int>& h) {
int n = h.size();
vector<int> l(n), r(n);
l[0] = h[0];
for(int i = 1; i < n; i ++ ) l[i] = max(l[i - 1], h[i]);
r[n - 1] = h[n - 1];
for(int i = n - 2; i >= 0; i -- ) r[i] = max(r[i + 1], h[i]);
int ans = 0;
for(int i = 0; i < n; i ++ )
ans += min(l[i], r[i]) - h[i];
return ans;
}
};
滑动窗口 2 题
3 无重复字符的最长字串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n = s.size();
int l = 0, r = 0;
int ans = 0;
unordered_map<char, int> cnt;
while(r < n) {
cnt[s[r]] ++;
while(l < n && cnt[s[r]] >= 2) {
cnt[s[l]] --;
l ++;
}
ans = max(ans, r - l + 1);
r ++;
}
return ans;
}
};
438 找到字符串中所有字母异位词
class Solution {
public:
bool vec_eq(vector<int> a, vector<int> b) {
int n = a.size();
for(int i = 0; i < 26; i ++ )
if(a[i] != b[i]) return false;
return true;
}
vector<int> findAnagrams(string s, string p) {
int n = s.size(), m = p.size();
vector<int> cnts(26), cntp(26), ans;
for(auto x : p)
cntp[x - 'a'] ++;
int l = 0, r = 0;
while(r < n) {
cnts[s[r] - 'a'] ++;
if(r - l + 1 == m) {
if(vec_eq(cnts, cntp)) ans.push_back(l);
cnts[s[l] - 'a'] --;
l ++;
}
r ++;
}
return ans;
}
};
字串 3 题
560 和为 k 的子数组
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int n = nums.size();
vector<int> sum(n + 1, 0);
for(int i = 0; i < n; i ++ ) {
sum[i + 1] = sum[i] + nums[i];
}
int ans = 0;
unordered_map<int, int> mp;
for(int i = 0; i <= n; i ++ ) {
ans += mp[sum[i] - k];
mp[sum[i]] ++;
}
return ans;
}
};
239 滑动窗口最大值
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
int n = nums.size();
priority_queue<pair<int, int>> pq;
vector<int> ans;
for(int i = 0; i < k; i ++ ) {
pq.push({nums[i], i});
}
ans.push_back(pq.top().first);
for(int i = k; i < n; i ++ ) {
pq.push({nums[i], i});
while(pq.top().second <= i - k) pq.pop();
ans.push_back(pq.top().first);
}
return ans;
}
};
76 最小覆盖字串
// TODO
class Solution {
public:
string minWindow(string s, string t) {
int n = s.size(), m = t.size();
int l = 0, r = 0;
vector<int> cnt(52, 0), cnt2(52, 0);
for(auto ch: t) {
if(ch >= 'A' && ch <= 'Z') cnt2[ch - 'A'] ++;
else cnt2[ch - 'a' + 26] ++;
}
int ans = 1e6;
int x = -1, y = -1;
while(r < n) {
if(s[r] >= 'A' && s[r] <= 'Z') cnt[s[r] - 'A'] ++;
else cnt[s[r] - 'a' + 26] ++;
// cnt[s[r]] ++;
bool ok = true;
for(int i = 0; i < 52; i ++ ) {
if(cnt[i] < cnt2[i]) {ok = false; break;}
}
while(ok) {
if(r - l + 1 <= ans) {
ans = r - l + 1;
x = l, y = r;
}
if(s[l] >= 'A' && s[l] <= 'Z') cnt[s[l] - 'A'] --;
else cnt[s[l] - 'a' + 26] ++;
// cnt[s[l]] --;
l ++;
for(int i = 0; i < 52; i ++ ) {
if(cnt[i] < cnt2[i]) {ok = false; break;}
}
}
r ++;
}
string ss = "";
if(x == -1 || y == -1) return ss;
else return s.substr(x, y - x + 1);
}
};
普通数组 5 题
53 最大子数组和
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n);
dp[0] = nums[0];
for(int i = 1; i < n; i ++ ) {
dp[i] = max(dp[i - 1] + nums[i], nums[i]);
}
int ans = -2e9;
for(int i = 0; i < n; i ++ ) {
ans = max(ans, dp[i]);
}
return ans;
}
};
56 合并数组
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> ans;
int n = intervals.size();
sort(intervals.begin(), intervals.end());
int st = -1e9, ed = -1e9;
for(int i = 0; i < n; i ++ ) {
if(intervals[i][0] > ed) {
if(ed != -1e9) ans.push_back({st, ed});
st = intervals[i][0], ed = intervals[i][1];
}
ed = max(ed, intervals[i][1]);
}
ans.push_back({st, ed});
return ans;
}
};
189 轮转数组
方法一:
class Solution {
public:
// 直接模拟的做法,复杂度 o(N)
void rotate(vector<int>& nums, int k) {
int n = nums.size();
vector<int> a(n);
for(int i = 0; i < n; i ++ ) {
a[(i + k) % n] = nums[i];
}
nums = a;
}
};
方法二:
class Solution {
public:
// 原地算法,旋转数组,制定起始位置的数组旋转一下即可
void reverse(vector<int>& nums, int start, int end) {
while (start < end) {
swap(nums[start], nums[end]);
start += 1;
end -= 1;
}
}
void rotate(vector<int>& nums, int k) {
k %= nums.size();
reverse(nums, 0, nums.size() - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.size() - 1);
}
};
238 除自身以外的数的乘积
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int n = nums.size();
vector<int> ans(n), l(n), r(n);
l[0] = 1;
r[n - 1] = 1;
for(int i = 1; i < n; i ++ ) {
l[i] = l[i - 1] * nums[i - 1];
}
for(int i = n - 2; i >= 0; i -- ) {
r[i] = r[i + 1] * nums[i + 1];
}
for(int i = 0; i < n; i ++ ) {
ans[i] = l[i] * r[i];
}
return ans;
}
};
41 缺失的第一个正数
// TODO
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
unordered_map<int, int> mp;
for(auto x : nums) mp[x] = 1;
int ans = -1;
for(int i = 1; i ; i ++ ) {
if(mp[i] == 0) {
ans = i;
break;
}
}
return ans;
}
};