文章目录
一、哈希
1.两数之和
1. 两数之和
cpp
复制代码
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> mp;
for (int i = 0; i < nums.size(); i++) {
auto num = mp.find(target - nums[i]);
if (num != mp.end()) {
return {i,num -> second};
}
else {
mp[nums[i]] = i;
}
}
return {-1,-1};
}
};
2.字母异位词分组
49. 字母异位词分组
cpp
复制代码
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
if (strs.size() == 0)return res;
unordered_map<string,vector<string>> mp;
for (auto t : strs) {
string str = t;
sort(str.begin(),str.end());
mp[str].push_back(t);
}
for (auto it = mp.begin(); it != mp.end(); it ++) {
res.push_back(it -> second);
}
return res;
}
};
3.最长连续序列
128. 最长连续序列
cpp
复制代码
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if (nums.size() == 0) return 0;
unordered_set<int> mp;
for (const int&nun : nums) {
mp.insert(num);
}
int res = 0;
for (auto ch : mp) {
if (!mp.count(ch - 1)) {
int curNum = ch;
int curStreak = 1;
while (mp.count(curNum + 1)) {
curNum += 1;
curStreak += 1;
}
res = max(res,curStreak);
}
}
return res;
}
};
二、双指针
4. 移动零
283. 移动零
cpp
复制代码
class Solution {
public:
void moveZeroes(vector<int>& nums) {
if (nums.size() == 0) return ;
int slow = 0;
int fast = 0;
while (fast < nums.size()) {
if (nums[fast] != 0) {
nums[slow ++] = nums[fast];
}
fast ++;
}
for (int i = slow; i < nums.size(); i++) {
nums[i] = 0;
}
}
};
5.盛最多水的容器
11. 盛最多水的容器
cpp
复制代码
class Solution {
public:
int maxArea(vector<int>& height) {
int i = 0, j = height.size() - 1;
int res = 0;
while (i < j) {
res = height[i] < height[j] ?
max(res,(j - i) * height[i ++]) :
max(res,(j - i) * height[j --]) ;
}
return res;
}
};
6.三数之和
15. 三数之和
cpp
复制代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
if (nums.size() == 0) return res;
sort(nums.begin(),nums.end());
if (nums[0] > 0) return res;
for (int k = 0; k < nums.size() - 2; k ++) {
if (k > 0 && nums[k] == nums[k - 1]) continue;
int i = k + 1,j = nums.size() - 1;
while (i < j) {
int sum = nums[k] + nums[i] + nums[j];
if (sum < 0) {
while (i < j && nums[i] == nums[++i]) ;
}
else if(sum > 0) {
while (i < j && nums[j] == nums[--j]) ;
}
else {
res.push_back(vector<int>{nums[k], nums[i], nums[j]});
while (i < j && nums[i] == nums[++i]) ;
while (i < j && nums[j] == nums[--j]) ;
}
}
}
return res;
}
};
7.接雨水
42. 接雨水
三、滑动窗口
8.无重复字符的最长子串
3. 无重复字符的最长子串
cpp
复制代码
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char,int> windows;
int left = 0,right = 0;
int res = 0;
int n = s.size();
while (right < n) {
char c = s[right];
right ++;
windows[c] ++;
while (windows[c] > 1) {
char d = s[left];
left ++;
windows[d] --;
}
res = max(res,right - left);
}
return res;
}
};
9.找到字符串中所有字母异位词
438. 找到字符串中所有字母异位词
cpp
复制代码
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
unordered_map<char,int> need,window;
for (char c : p) need[c] ++;
int left = 0,right = 0;
int vaild = 0;
vector<int> res;
while (right < s.size()) {
char c = s[right];
right ++;
if (need.count(c)) { // 如果需要这个元素
window[c] ++; // 窗口中的值 ++
if (window[c] == need[c]) { // 如果窗口中的值和需要的值相等
vaild++; // 有效值++{}
}
}
while (right - left >= p.size()) { // 当现在的左右差大于子串p的大小
if (vaild == need.size()) // 如果有效值 == need
res.push_back(left); // 加入
char d = s[left]; // 缩小窗口
left ++;
if (need.count(d)) {
if (window[d] == need[d])
vaild--;
window[d]--;
}
}
}
return res;
}
};
四、子串
10.和为 K 的子数组
560. 和为 K 的子数组
cpp
复制代码
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int,int> mp;
mp[0] = 1;
int count = 0,pre = 0;
for (auto x : nums) {
pre += x;
if (mp.find(pre - k) != mp.end()) {
count += mp[pre - k];
}
mp[pre] ++;
}
return count;
}
};