1. 四数之和 & 四数之和 II
- 四数之和
这道题的其实并不适合用哈希表去做,在哈希表上去重的话效果并不是很好。整体思路虽然还是a + b = target - (c + d)
,但是涉及到去重和剪枝,就会比较麻烦,如果真的记不下来的话可以暂时不做剪枝,先把去重的逻辑理解好。
不做剪枝的版本:
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
int size = nums.size();
sort(nums.begin(), nums.end()); // 记得排序
for (int i = 0; i < size; i++) {
if (i > 0 && nums[i] == nums[i - 1]) { // 去重逻辑
continue;
}
for (int j = i + 1; j < size; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) { //
continue;
}
// twoSum
int start = j + 1;
int end = size - 1;
while (start < end) {
// 注意这里一定要加个long,要不然可能会溢出
if ((long) nums[i] + nums[j] + nums[start] + nums[end] == target) {
result.push_back(vector<int>{nums[i], nums[j],
nums[start], nums[end]});
while (start < end && nums[start] == nums[start + 1]) // 先做去重
start++;
start++; // 再做收缩
while (start < end && nums[end] == nums[end - 1])
end--;
end--;
} else if ((long)nums[i] + nums[j] + nums[start] + nums[end] < target)
start++;
else
end--;
}
}
}
return result;
}
};
- 四数之和 II
如果不涉及到去重的话,那这题就简单多了,直接使用哈希表就可以解了。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int> umap;
for (int a : nums1) {
for (int b : nums2) {
umap[a + b]++;
}
}
int sum = 0;
for (int c : nums3) {
for (int d : nums4) {
if (umap.find(-(c + d)) != umap.end()) {
sum += umap[-(c + d)];
}
}
}
return sum;
}
};
2. 三数之和
题目链接:三数之和
跟四数之和类似,如果理解困难的话可以先不管剪枝,力扣也是可以过的,之后再慢慢加上来,不着急。但是在二刷的时候也要弄懂剪枝!
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++) {
if (i > 0 && nums[i] == nums[i - 1])
continue;
int start = i + 1;
int end = nums.size() - 1;
while (start < end) {
if ((long)nums[i] + nums[start] + nums[end] == 0) {
result.push_back(vector<int>{nums[i], nums[start], nums[end]});
while (start < end && nums[start] == nums[start + 1])
start++;
start++;
while (start < end && nums[end] == nums[end - 1])
end--;
end--;
} else if ((long)nums[i] + nums[start] + nums[end] < 0) {start++;}
else {end--;}
}
}
return result;
}
};
3. 替换数字
题目链接:替换数字
这里要注意的其实就是vector
类型的resize
操作,其实思路有了之后这题很好实现。
#include <iostream>
using namespace std;
int main() {
string s;
while (cin >> s) {
int oriSize = s.size();
int numCnt = 0;
for (char ch : s) {
if (ch >= '0' && ch <= '9') {
numCnt++;
}
}
s.resize(oriSize + numCnt * 5); // 就这个地方
int right = s.size() - 1;
int left = oriSize - 1;
while (left >= 0) {
if (s[left] > '9' || s[left] <'0') {
s[right--] = s[left--];
} else {
s[right--] = 'r';
s[right--] = 'e';
s[right--] = 'b';
s[right--] = 'm';
s[right--] = 'u';
s[right--] = 'n';
left--;
}
}
cout << s;
}
}
4. 反转字符串中的单词
题目链接:反转字符串中的单词
这道题感觉是考察一个综合的模拟过程,只要细心一点问题应该不大。
class Solution {
public:
string reverseWords(string s) {
// 去掉前面的空格
int index = 0;
while (s[index] == ' ') {index++;};
s = string(s.begin() + index, s.end());
// 去掉后面的空格
reverse(s.begin(), s.end());
index = 0;
while (s[index] == ' ') {index++;};
s = string(s.begin() + index, s.end());
// 去掉中间的空格
int fast = 0;
int slow = 0;
int cnt = 0;
while (fast < s.size()) {
if (s[fast] == ' ' && s[fast + 1] == ' ') {
fast++;
cnt++;
} else {
s[slow++] = s[fast++];
}
}
s = string(s.begin(), s.end() - cnt);
// 反转字符串
fast = 0;
slow = 0;
while (fast < s.size()) {
if (s[fast] == ' ') {
reverse(s.begin() + slow, s.begin() + fast);
slow = fast + 1;
}
fast++;
}
reverse(s.begin() + slow, s.end()); // 还要多一次反转,因为我先把前后的空格去掉了,这样子最后一个单词不会进反转逻辑。
return s;
}
};
5. 右旋字符串
题目链接:右旋字符串
你会发现,这道题只要见过了,就没有任何难度。
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
string s;
int k;
while (cin >> k >> s) {
reverse(s.begin(), s.end());
reverse(s.begin(), s.begin() + k);
reverse(s.begin() + k, s.end());
cout << s;
}
}
6. 用栈实现队列
题目链接:用栈实现队列
没有人会这么做的,但是你就问八股要不要考吧。
class MyQueue {
public:
MyQueue() {
}
void push(int x) {
in.push(x);
}
int pop() {
if (out.empty()) {
while (!in.empty()) {
out.push(in.top());
in.pop();
}
}
int reuslt = out.top();
out.pop();
return reuslt;
}
int peek() {
if (out.empty()) {
while (!in.empty()) {
out.push(in.top());
in.pop();
}
}
int reuslt = out.top();
return reuslt;
}
bool empty() {
if (in.empty() && out.empty()) {
return true;
}
return false;
}
private:
stack<int> in;
stack<int> out;
};
7. 用队列实现栈
题目链接:用队列实现栈
没有人会这么做的,但是你就问八股要不要考吧。
class MyStack {
public:
MyStack() {
}
void push(int x) {
q1.push(x);
}
int pop() {
while (q1.size() != 1) {
q2.push(q1.front());
q1.pop();
}
int res = q1.front();
q1.pop();
while (!q2.empty()) {
q1.push(q2.front());
q2.pop();
}
return res;
}
int top() {
while (q1.size() != 1) {
q2.push(q1.front());
q1.pop();
}
int res = q1.front();
q2.push(q1.front());
q1.pop();
while (!q2.empty()) {
q1.push(q2.front());
q2.pop();
}
return res;
}
bool empty() {
return q1.empty();
}
private:
queue<int> q1;
queue<int> q2;
};