使用哈希表解决几个常见算法题

本文介绍了哈希表在复杂链表复制、两数和问题及计算最多共线点数的应用。利用哈希表高效查找特性解决实际问题。

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

简介

哈希表是一种非常常见的KV型的数据结构,他的搜索效率十分高,时间复杂度通常都在O(N)。在C++11之后,引入了容器 unordered_map,它的底层实现就是哈希表,所以我们在需要使用哈希表的时候通常就利用unordered_map。

问题

1.复杂链表的复制;

2.两数和问题;

3.计算最多有几个点在同一直线上;

一.复杂链表的复制

问题分析:

复杂链表即链表结点结构中除了数据域data和next指针之外,还有一个指向随机结点的随机结点指针域。要对这种链表进行复制其难点是如果按照和普通链表一样一个一个结点向后复制的话,就无法正确的找到随机指针域所指向的结点。

解决方案:

这里我们知道哈希表可以通过key值对应相应的value值,那么就可以把每个结点的地址设为key值和value值放入一个哈希表之中。先把链表按照普通链表复制一样一个一个结点的复制(此时复制只包括data域和next指针域),并同时把链表的所有结点都通过结点地址映射到哈希表的相应位置。最后再从头遍历一遍原链表,当遇到某个结点的随机指针域不为空的时候,就通过哈希表的映射关系把随机指针赋到复制链表相应结点的随机指针域之中。

代码实现

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

struct RandomListNode {
    int label;
    RandomListNode *next, *random;
    RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
};

RandomListNode *copyRandomList(RandomListNode *head)
{//使用容器
    unordered_map<RandomListNode*, RandomListNode*> tmp;
    RandomListNode *ret = new RandomListNode(0);
    RandomListNode *p = head;
    RandomListNode *q = ret;

    while (p)
    {
        RandomListNode *copy = new RandomListNode(p->label);
        tmp[p] = copy;
        q->next = copy;
        q = q->next;
        p = p->next;
    }
    p = head;
    while (p)
    {
        if (p->random)
            tmp[p]->random = tmp[p->random];

        p = p->next;
    }

    return ret->next;
}

二.两数和问题

问题描述:

给一个整数数组,找到两个数使得他们的和等于一个给定的数 target。你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 1 到 n,不是以 0 开头。
例:
给出 numbers = [2, 7, 11, 15], target = 9, 返回 [1, 2]。

问题分析:

这个问题可以转化为以一个数为基准,再用和减去基准数得到他们的差值,再去在数组中找这个差值的问题。这个时候就可以以数组存放的数值为key值,数值对应的数组下标为value值。利用哈希查找算法查找相应值的下标。

代码实现

vector<int> twoSum(vector<int> nums, int target)
{
    unordered_map<int, int> hash;
    vector<int> result;

    for (int i = 0; i < nums.size(); i++) 
    {
        if (hash.find(target - nums[i]) != hash.end())//判断一个值是否在哈希表中存在 
        {
            result.push_back(hash[target - nums[i]]+1);
            result.push_back(i+1);
            return result;
        }
        hash[nums[i]] = i;
    }

    result.push_back(-1);
    result.push_back(-1);
    return result;
    }

三.计算最多有几个点在同一直线上

问题分析:

计算二维平面上最多有几个点在同一直线上,那么一个很直接的方法就是利用斜率作为哈希表的key值,value中放入一个计数器,当遇到斜率相等的情况就使其对应计数器加一。注意,两条线的斜率相等不一定这两条线就是在同一条直线上,还需要一个条件是这两条线通过同一个点。所以我们的处理方法是找到一个基准点(每个点都要做一次基准点,除开最后一个点,保证每两个点都构成一次直线),计算后面每个点与其形成的直线的斜率。

代码实现

struct Point 
{
    int x;
    int y;
    Point() : x(0), y(0) {}
    Point(int a, int b) 
        : x(a)
        , y(b) 
    {}
};

int MaxPoint(vector<Point> Points)
{
    unordered_map<float, int> mp;
    int ret = 0;
    for (int i = 0; i < Points.size(); i++)
    {
        mp.clear();
        mp[INT_MIN] = 0;//设置哈希表value初值为0;
        int self = 1;
        for (int j = 0; j < Points.size(); j++)
        {
            if (i == j)
                continue;
            if (Points[i].x == Points[j].x && Points[i].y == Points[j].y)
            {//判断两个点是否完全一样
                self++;
                continue;
            }
            float k = Points[i].x == Points[j].x ? INT_MAX : (float)(Points[j].y - Points[i].y)/(Points[j].x - Points[i].x);
            //横坐标相等时说明此时两点构成的直线与y轴平行,不相等则计算其k
            //这里计算的key值要转成float型,不然会导致计算结果不准确
            mp[k]++;//k斜率计数加一
        }
        for (auto i = mp.begin(); i != mp.end(); i++)
        {
            if (i->second + self > ret)
            {
                ret = i->second + self;
            }
        }
    }
    return ret;
}
这个错误是由于无法连接到本地主机的10248端口导致的。这个端口通常是kubelet进程监听的端口,用于健康检查。出现这个错误可能是由于kubelet进程没有正确启动或者配置错误导致的。 解决这个问题的方法是检查kubelet进程的状态和配置。你可以按照以下步骤进行操作: 1. 检查kubelet进程是否正在运行。你可以使用以下命令检查kubelet进程的状态: ```shell systemctl status kubelet ``` 如果kubelet进程没有运行,你可以使用以下命令启动它: ```shell systemctl start kubelet ``` 2. 检查kubelet的配置文件。你可以使用以下命令查看kubelet的配置文件路径: ```shell kubelet --kubeconfig /etc/kubernetes/kubelet.conf --config /var/lib/kubelet/config.yaml --bootstrap-kubeconfig /etc/kubernetes/bootstrap-kubelet.conf config view ``` 确保配置文件中的端口号和地址正确,并且与你的环境相匹配。 3. 检查网络连接。你可以使用以下命令检查是否可以连接到localhost的10248端口: ```shell curl -sSL http://localhost:10248/healthz ``` 如果无法连接,请确保端口没有被防火墙或其他网络配置阻止。 4. 检查docker的配置。有时候,kubelet进程依赖于docker进程。你可以按照以下步骤检查docker的配置: - 创建/etc/docker目录: ```shell sudo mkdir /etc/docker ``` - 编辑/etc/docker/daemon.json文件,并添加以下内容: ```json { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ], "registry-mirrors": ["https://tdhp06eh.mirror.aliyuncs.com"] } ``` - 重启docker进程: ```shell systemctl restart docker ``` 请注意,以上步骤是一种常见解决方法,但具体解决方法可能因环境而异。如果以上步骤无法解决问题,请提供更多的错误信息和环境配置,以便我们能够更好地帮助你。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值