IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 面试必刷算法TOP101之哈希篇 TOP 22 -> 正文阅读

[数据结构与算法]面试必刷算法TOP101之哈希篇 TOP 22

两数相加Ⅱ

题目来源:leetcode

1、问题描述

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。

2、思路解析

思路一:哈希+反转链表
将俩个链表节点分别存储在hash数据结构中然后从尾部遍历相加,将相加结果保存在sum中,然后申请新节点,将新节点插入到新链表中这样得到的是结果链表的反向链表。最后将链表反转就可以
思路二:反转链表相加+反转链表
先将两个链表反转,这样就比较容易相加,相加后将最后得到的链表也进行反转就行
在这里插入图片描述
思路三:栈+反转链表
先将链表分别入栈,因为栈是先进先出这就导致头节点先进去未结点先出来这就方便运算,每加一次就申请一次新节点,最后将新节点插入到新链表中,最后也需要将新链表反转才能得到结果链表

3、代码实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    //哈希
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
         // write code here
         vector<int> v1;
        vector<int> v2;
        while(l1){
            v1.push_back(l1->val);
            l1=l1->next;
        }
        while(l2){
            v2.push_back(l2->val);
            l2=l2->next;
        }
        ListNode*proot=new ListNode(-1);
        ListNode*root=proot;
        int end1=v1.size()-1;
        int end2=v2.size()-1;
        int num=0;//进位
        while(end1>=0&&end2>=0){
            int sum=v1[end1]+v2[end2]+num;
            if(sum>=10){
                sum-=10;
                num=1;
            }else{
                num=0;
            }
            root->next=new ListNode(sum);
            root=root->next;
            end1--;
            end2--;
        }
        while(end1>=0){
            int sum=v1[end1]+num;
            if(sum>=10){
                sum-=10;
                num=1;
            }else{
                num=0;
            }
            root->next=new ListNode(sum);
            root=root->next;
            end1--;
        }
        while(end2>=0){
            int sum=v2[end2]+num;
            if(sum>=10){
                sum-=10;
                num=1;
            }else{
                num=0;
            }
            root->next=new ListNode(sum);
            root=root->next;
            end2--;
        }
        //检测进制位是不是为0
        if(num!=0){
            root->next=new ListNode(num);
        }
        //反转链表
        ListNode *cur=proot->next->next;
        ListNode*node=proot->next;
        node->next=NULL;
        while(cur){
            ListNode*node1=cur->next;
            cur->next=node;
            node=cur;
            cur=node1;
        }
        
        return node;

    }
};
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head1 ListNode类 
     * @param head2 ListNode类 
     * @return ListNode类
     */
    //反转链表
    //相加后再反转
    ListNode* FAN(ListNode*root){
         ListNode*node1=root;
        ListNode*node2=root->next;
        node1->next=NULL;
        while(node2){
            ListNode*node=node2->next;
            node2->next=node1;
            node1=node2;
            node2=node;
            
        }
        return node1;
    }
    ListNode* addInList(ListNode* head1, ListNode* head2) {
        if(head1==NULL&&head2==NULL){
            return NULL;
        }
        if(head1==NULL){
         return head2;
        }else if(head2==NULL){
            return head1;
        }
       //反转林链表
        ListNode*node=FAN(head1);
        ListNode*node1=FAN(head2);
        //链表相加
        ListNode*root=new ListNode(-1);
        ListNode*cur=root;
        int i=0;
        int sum=0;
        while(node&&node1){
            sum=node->val+node1->val+i;
            if(sum>=10){
                sum-=10;
                i=1;
            }else{
                i=0;
            }
            cur->next=new ListNode(sum);
            cur=cur->next;
            node=node->next;
            node1=node1->next;
        }
        while(node){
             sum=node->val+i;
            if(sum>=10){
                sum-=10;
                i=1;
            }else{
                i=0;
            }
            cur->next=new ListNode(sum);
            cur=cur->next;
            node=node->next;
        }
        while(node1){
             sum=node1->val+i;
            if(sum>=10){
                sum-=10;
                i=1;
            }else{
                i=0;
            }
            cur->next=new ListNode(sum);
            cur=cur->next;
            node1=node1->next;
        }
        if(i==1){
            cur->next=new ListNode(i);
        }
        //反转链表
        ListNode*head=FAN(root->next);
       
        return head;
    }
};

四数相加

题目来源:Leetcode

1、问题描述

给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

2、思路解析

思路一:循环暴力破解
该思路简单容易理解,就是四个for循环遍历每中排列,然后判断是不是符合条件,符合条件就将结果保存在数组中。虽然思路简单,但是时间复杂度为O(N^4),随着数据量的增加运算时间也在不断增加。
思路二:哈希
将数组分成两组,数组A和数组B为一组,将A[i]+B[j]=sum结果保存在hashamap中充当键值,其出现次数为values,也就是双for循环遍历A数组和B数组将结果保存在map的键值中,将出现次数保存在values。数组C和数组D为一组,双for循环遍历数组C和数组D,寻找map中是不是存在-(C[i]+D[j])也就是sum,如果存在(也即是说出现sum+C[i]+D[j]0的情况,出现的次数N就是结果为C[i]+D[j]+sum0有N种情况)就将出现次数加起来,最后将次数相加的结果返回就行

3、代码实现

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        int ret=0;
        for(int i=0;i<nums1.size();i++){
            for(int j=0;j<nums2.size();j++){
                for(int n=0;n<nums3.size();n++){
                    for(int m=0;m<nums4.size();m++){
                        if(nums1[i]+nums2[j]+nums3[n]+nums4[m]==0){
                            ret++;
                        }
                    }
                }
            }
        }
        return ret++;
    }
};
class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int,int> m;
        
        for(int i=0;i<nums1.size();i++){
            for(int j=0;j<nums2.size();j++){
            //结果保存早键值,出现次数保存在values中
                m[nums1[i]+nums2[j]]++;
            }
        }
        int num=0;
        for(int i=0;i<nums3.size();i++){
            for(int j=0;j<nums4.size();j++){
                //找到相反数将对应的次数相加
                if(m.count(-(nums3[i]+nums4[j]))){
                    num+=m[-(nums3[i]+nums4[j])];
                }
            }
        }
        
        return num;

    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:59:05  更:2022-05-09 12:59:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:29:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码