《编程之法》:寻找和为定值的两个数

本文介绍两种高效算法来寻找数组中和为特定值的数对。一种利用哈希表快速定位配对元素,另一种通过排序及双指针技巧逐步逼近目标和。这两种方法适用于不同场景,提供了解决该问题的有效途径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

输入一个整数数组和一个整数,在数组中查找一对数,满足它们的和正好是输入的那个整数。如果有多对数的和等于输入的整数,输出任意一对即可。

思路一:无序则hash

建立一张hash表,存储每个整数,然后遍历数组的前一半,在hash表中查找是否有sum-k的这个数存在。

代码

//
// Created by huxijie on 17-3-18.
// 寻找和为定值的两个数

#include <iostream>
using namespace std;

typedef struct HashNode{
    int data;
    struct HashNode *next;
}hashNode;

class HashTable{
private:
    const static int size = 25;
    hashNode *hash[size];
public:
    HashTable();
    ~HashTable();
    int getHashKey(int data);   //获取data所对应的键
    void insertHash(int data);  //将data插入到hash表中
    bool findData(int data);    //查找data是否在hash表中
    void findSumTwo(int *src,int len,int sum);  //找到所有和等于sum的数对

};

HashTable::HashTable() {
    for (int i = 0; i < size; ++i) {
        hash[i] = NULL;
    }
}

HashTable::~HashTable() {
    for (int i = 0; i < size; ++i) {
        hashNode *p = hash[i];
        while (p != NULL) {
            hashNode *tmp = p;
            p = p->next;
            delete (tmp);
        }
    }
}

//获取data所对应的键
int HashTable::getHashKey(int data) {
    return data % size;
}

//将data插入到hash表中
void HashTable::insertHash(int data) {
    int key = getHashKey(data);
    hashNode *p = hash[key];

    while (p != NULL) {
        if (p->data == data) {
            return;
        }
        p = p->next;
    }

    hashNode *newNode = new hashNode;
    newNode->data = data;
    newNode->next = hash[key];
    hash[key] = newNode;
}

//查找data是否在hash表中
bool HashTable::findData(int data) {
    int key = getHashKey(data);
    hashNode *p = hash[key];
    while (p != NULL) {
        if (p->data == data) {
            return true;
        }
        p = p->next;
    }
    return false;
}

//找到所有和等于sum的数对
void HashTable::findSumTwo(int *src,int len,int sum) {
    for (int i = 0; i < len; ++i) {
        insertHash(src[i]);
    }

    for (int j = 0; j < len / 2; ++j) {
        if (findData(sum - src[j])) {  //这里可根据是要寻找一对还是多对进行调整
            cout << src[j] << "+" << sum - src[j] << "=" << sum << endl;
        }
    }
}



int main() {
    HashTable hashTable;
    int n = 8;
    int data[n] = {1, 2, 4, 5, 7, 11, 15, 13};
    hashTable.findSumTwo(data, n, 15);

    return 0;
}

思路二:先排序再首尾指针夹逼

先将数组进行排序,然后设2个指针,分别指向首和尾,比较它们的和与要求的整数之间的大小,若小了,则首指针++; 若大了,则尾指针–;相等则是输出。

代码

//
// Created by huxijie on 17-3-18.
// 寻找和为定值的两个数

#include <iostream>
#include <algorithm>
using namespace std;

void findSumTwo(int src[],int len,int sum) {
    sort(src, src + len);
    int i = 0, j = len - 1;

    while (i < j) {
        int tmp = src[i] + src[j];
        if (tmp > sum) {
            j--;
        } else if (tmp < sum) {
            i++;
        } else {    //这里可根据是要寻找一对还是多对进行调整
            cout<<src[i]<<"+"<<src[j]<<"="<<sum<<endl;
            i++;
            j--;
        }
    }
}

int main() {
    int n = 8;

    int data[n] = {1, 2, 4, 5, 7, 11, 15, 13};
    findSumTwo(data, n, 15);
}

运行结果

2+13=15
4+11=15

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值