马上要面试了,把前些天在LeetCode上刷的题再看一遍。
写上注释,算复习了,也方便以后复习。
带 * 号的为忘记怎么做的。
36. 1. 两数之和(哈希表)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ret;
int n = nums.size();
int key;
unordered_map<int, int> m;
for (int i = 0; i < n; i++) {
key = target - nums[i];
// 如果找到了,就返回
if (m.find(key) != m.end()) {
ret.push_back(m[key]);
ret.push_back(i);
break;
}
// 否则插入当前值
m.insert(pair<int, int>(nums[i], i));
}
return ret;
}
};
37. 202. 快乐数(哈希表)
class Solution {
public:
int f(int n) {
// 计算各位数字平方和
int sum = 0;
int temp;
while (n != 0) {
temp = n % 10;
sum += temp * temp;
n /= 10;
}
return sum;
}
bool isHappy(int n) {
if (n == 1) return true;
unordered_set<int> record;
int temp = n;
do {
// 对一个set进行插入后,如果其second为false,则表明该记录已经存在,插入失败
if (!record.insert(temp).second) return false;
temp = f(temp);
} while (temp != 1);
return true;
}
};
38. 344. 反转字符串(对撞指针)
class Solution {
public:
void reverseString(vector<char>& s) {
int n = s.size();
int left = 0, right = n - 1;
// 对撞指针
while (left < right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left ++, right --;
}
}
};
39. 209. 长度最小的子数组(滑动窗口)
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
// 以下初始化,都是基于闭区间[left, right]
int left = 0, right = 0;
int sum = nums[0];
int ans;
if (sum >= s) ans = 1; // 不要漏了这种情况
else ans = n + 1; // 因为要找最小值,所以初始化为最大值
while (left < n) {
// 如果不够,向右扩展
if (right + 1 < n && sum < s) {
right ++;
sum += nums[right];
}
// 如果超了,或者到达终点了,左侧缩小,尝试是否出现更优解
else {
sum -= nums[left];
left ++;
}
// 更新答案
if (sum >= s) {
ans = min(ans, right - left + 1);
}
}
if (ans == n + 1) return 0;
return ans;
}
};
40. 76. 最小覆盖子串(滑动窗口)
class Solution {
public:
string minWindow(string s, string t) {
int len = s.length();
// 遍历目标串,知每个字符需要多少个
unordered_map<char, int> target, window;
for (char ch : t) target[ch]++;
int left = 0, right = 0; // 当前窗口为[left..right)
string ans = ""; // 返回值
int m = len + 1; // 长度最小值,初始化为最大值
int matched = 0; // 已经匹配的字符个数
while (right < len) {
// 处理right号字符
char chr = s[right];
// 如果是需要匹配的字符
if (target.count(chr)) {
window[chr] ++;
// 必须是==,才表明是刚达到目标
if (window[chr] == target[chr]) {
matched ++;
}
}
right ++; // 保证当前窗口为[left..right)
// 尝试更新并缩小最优解
while (matched == target.size()) {
// 更新
if (right - left < m) {
m = right - left;
ans = s.substr(left, m);
}
// 缩小
char chl = s[left];
if (target.count(chl)) {
window[chl] --;
// 必定是==,不过这里换成<target[chl]也可以
if (window[chl] == target[chl] - 1) {
matched --;
}
}
left ++;
}
}
return ans;
}
};