数据结构-哈希表II

哈希表-四数之和

题目链接

//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非常费劲,毕竟编译器不会在这种问题上报错,所以还需要把握好细节。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值