哈希表-四数之和
//Hash哈希表-四数相加II
#include<bits/stdc++.h>
using namespace std;
unordered_map<int, int> Map;
int n;
int a[200], b[200], c[200], d[200];
int main(){
cin >> n;
for (int i = 0; i < n; i++){
cin >> a[i] >> b[i] >> c[i] >> d[i];
}
for (int num1 : a){
for (int num2 : b){
Map[num1 + num2]++;
}
}
int count = 0;
for (int num1 : c){
for (int num2 : d){
if (Map.find(0 - (num1 + num2)) != Map.end()){
count += Map[0 - (num1 + num2)];
}
}
}
printf("%d\n", count);
return 0;
}
哈希表-赎金信
//Hash哈希表-赎金信
#include<bits/stdc++.h>
using namespace std;
unordered_map<char, int> Map;
string ransomNote, magazine;
int main(){
cin >> ransomNote >> magazine;
for (char ch : magazine){
Map[ch]++;
}
int temp = 0;
for (char ch : ransomNote){
if (Map.find(ch) != Map.end()){
if (Map[ch] == 0){
printf("false\n");
temp++;
break;
}
else {
Map[ch]--;
}
}
else {
printf("false\n");
temp++;
break;
}
}
if (temp == 0){
printf("true\n");
}
return 0;
}
三数之和
三指针,剪枝
//Hash哈希表-三数之和-三指针法
#include<bits/stdc++.h>
using namespace std;
int n, leftBorder, rightBorder;
int nums[3000], ans[1000][4];
int main(){
cin >> n;
for (int i = 0; i < n; i++){
cin >> nums[i];
}
sort(nums, nums + n);
int temp = 0;
for (int i = 0; i < n; i++){
if (nums[i] > 0){
break;
}
if (i > 0 && nums[i] == nums[i - 1]){
continue;
}
leftBorder= i + 1;
rightBorder = n - 1;
while (rightBorder > leftBorder){
if (nums[i] + nums[leftBorder] + nums[rightBorder] > 0){
rightBorder--;
}
else if(nums[i] + nums[leftBorder] + nums[rightBorder] < 0){
leftBorder++;
}
else {
ans[temp][0] = nums[i];
ans[temp][1] = nums[leftBorder];
ans[temp][2] = nums[rightBorder];
temp++;
while (rightBorder > leftBorder && nums[rightBorder] == nums[rightBorder - 1]){
rightBorder--;
}
while (rightBorder > leftBorder && nums[leftBorder] == nums[leftBorder + 1]){
leftBorder++;
}
rightBorder--;
leftBorder++;
}
}
}
for (int i = 0; i < temp; i++){
printf("%d %d %d\n", ans[i][0], ans[i][1], ans[i][2]);
}
return 0;
}
四数之和
四指针,剪枝
//Hash哈希表-四数之和-四指针
#include<bits/stdc++.h>
using namespace std;
int n, target;
int leftBorder, rightBorder;
int nums[200], ans[200][10];
int main(){
cin >> n;
for (int i = 0; i < n; i++){
cin >> nums[i];
}
sort(nums, nums + n);
cin >> target;
int temp = 0;
for (int k = 0; k <= n - 4; k++){
if (nums[k] > target && target >= 0) break;
if (nums[k] == nums[k - 1] && k > 0) continue;
for (int i = k + 1; i <= n - 3; i++){
if (nums[k] + nums[i] > target && target >= 0) break;
if (nums[i] == nums[i - 1] && i > k + 1) continue;
leftBorder = i + 1;
rightBorder = n - 1;
while (rightBorder > leftBorder){
if (nums[k] + nums[i] + nums[leftBorder] + nums[rightBorder] > target){
rightBorder--;
}
else if(nums[k] + nums[i] + nums[leftBorder] + nums[rightBorder] < target){
leftBorder++;
}
else {
ans[temp][0] = nums[k], ans[temp][1] = nums[i];
ans[temp][2] = nums[leftBorder], ans[temp++][3] = nums[rightBorder];
while (nums[leftBorder] == nums[leftBorder + 1] && rightBorder > leftBorder){
leftBorder++;
}
while (nums[rightBorder] == nums[rightBorder - 1] && rightBorder > leftBorder){
rightBorder--;
}
rightBorder--;
leftBorder++;
}
}
}
}
for (int i = 0; i < temp; i++){
printf("%d %d %d %d\n", ans[i][0], ans[i][1], ans[i][2], ans[i][3]);
}
return 0;
}
总结
对于多指针的使用更加熟练,三指针和四指针结合剪枝优化,同时对临界条件的判定更加准确,可能在某个问题中,+1和-1的区别天壤之别,for循环的循环次数也要把握好,不然debug非常费劲,毕竟编译器不会在这种问题上报错,所以还需要把握好细节。