D358周赛复盘:哈希表模拟⭐⭐+链表乘法翻倍运算(先反转)⭐⭐⭐

news2025/2/24 12:05:03

文章目录

    • 2815.数组中的最大数对和
      • 思路
      • 完整版
    • 2816.翻倍以链表形式表示的数字(先反转,再处理进位)
      • 思路
      • 完整版
    • 补充:206.反转链表(双指针法)
      • 完整版
    • 2817.限制条件下元素之间的最小绝对差(cpp不知道为什么超时了,java可以)

2815.数组中的最大数对和

给你一个下标从 0 开始的整数数组 nums 。请你从 nums 中找出和 最大 的一对数,且这两个数数位上最大的数字相等。

返回最大和,如果不存在满足题意的数字对,返回 -1

示例 1:

输入:nums = [51,71,17,24,42]
输出:88
解释:
i = 1 和 j = 2 ,nums[i] 和 nums[j] 数位上最大的数字相等,且这一对的总和 71 + 17 = 88 。 
i = 3 和 j = 4 ,nums[i] 和 nums[j] 数位上最大的数字相等,且这一对的总和 24 + 42 = 66 。
可以证明不存在其他数对满足数位上最大的数字相等,所以答案是 88 。

示例 2:

输入:nums = [1,2,3,4]
输出:-1
解释:不存在数对满足数位上最大的数字相等。

提示:

  • 2 <= nums.length <= 100
  • 1 <= nums[i] <= 104

思路

本题需要用哈希表来做,我们需要对应每个数位最大数字相应的数值

完整版

  • 注意是找一对数字,也就是只找两个数字。因此哈希表里面要存储每个数位最大数字对应的那个数字的值
class Solution {
public:
    //获取数字最大位
    int getMaxDigit(int num){
        int maxDigit =-1;
        //只要Num存在就继续
        while(num){
            maxDigit=max(maxDigit,num%10);//单个数字比较,%10得到单个数字
            num/=10;//去掉最后一位
        }
        return maxDigit;
    }
    int maxSum(vector<int>& nums) {
        //创建哈希表存储最大位和与其关联的数字最大值
        unordered_map<int,int>maxDigitMap;
        int result=-1;
        int maxD=-1;
        for(int num:nums){
            maxD=getMaxDigit(num);
            //如果这个数字已经在哈希表里面
            if(maxDigitMap.count(maxD)){
                //累积结果取最大值
                result = max(result,maxDigitMap[maxD]+num);
                //注意:目标是找到和最大的一对数字,也就是两个数字!所以哈希表要存储最大的数字
                maxDigitMap[maxD]=max(maxDigitMap[maxD],num);//更新最大位相同数字的和
            }
            else{
                maxDigitMap[maxD]=num;
            }
        }
        return result;
    }
};

2816.翻倍以链表形式表示的数字(先反转,再处理进位)

给你一个 非空 链表的头节点 head ,表示一个不含前导零的非负数整数。

将链表 翻倍 后,返回头节点 head

示例 1:
在这里插入图片描述

输入:head = [1,8,9]
输出:[3,7,8]
解释:上图中给出的链表,表示数字 189 。返回的链表表示数字 189 * 2 = 378 。

示例 2:

在这里插入图片描述

输入:head = [9,9,9]
输出:[1,9,9,8]
解释:上图中给出的链表,表示数字 999 。返回的链表表示数字 999 * 2 = 1998 。

提示:

  • 链表中节点的数目在范围 [1, 10^4]
  • 0 <= Node.val <= 9
  • 生成的输入满足:链表表示一个不含前导零的数字,除了数字 0 本身。

思路

  1. 反转链表:

    为了方便计算,我们首先将链表反转。这样我们可以从数字的低位(链表的头部)开始处理,方便处理进位。例如数字 189 的链表 [1, 8, 9] 反转后会变成 [9, 8, 1]

  2. 翻倍处理:

    • 对每一个节点,翻倍它的值并加上可能的进位(carry)。例如,如果当前节点的值为9,翻倍后是18,再加上可能的进位,这样这个节点的新值就是8,进位就是1。
    • 这个进位会被加到下一个节点的值上,这样一直处理到链表的尾部。
    • 如果链表的最后一个节点有进位,就需要添加一个新的节点来存储这个进位。
  3. 再次反转链表:

    在完成上述的翻倍处理后,链表仍然是反转的状态,所以我们需要再次反转它以得到正确的答案。

这种方法的好处是我们只需要遍历两次链表,一次是反转,一次是翻倍处理,所以总体的时间复杂度是 O(n),其中 n 是链表的长度。

完整版

  • 注意乘法的处理方式,先反转,再相乘,相乘完了之后更新进位。(注意相乘的时候要加上进位)
  • 如果是最后一个数字且进位不为0,那么需要再加一个数值为0的空节点,用于存放carry!
/**
 * 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* reverseList(ListNode* head){
        ListNode* cur = head;
        ListNode* pre = nullptr;
        while(cur!=nullptr){
            ListNode* temp = cur->next;
            cur->next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
    }
    ListNode* doubleIt(ListNode* head) {
        if(head==nullptr) return nullptr;
        //反转链表
        head = reverseList(head);
        //创建一个指针指向链表头部
        ListNode* cur = head;
        int carry=0;//初始化进位是0

        //遍历链表
        while(cur!=nullptr){
            int temp = cur->val *2 + carry;//加上进位,和普通乘法一样
            cur->val = temp%10;//当前节点数值是加上进位后的个位数
            carry = temp/10;//更新进位

            //注意特殊情况!如果当前节点是链表最后一个并且还有进位
            if(cur->next==nullptr&&carry){
                cur->next=new ListNode(0);//增加一个新的节点,用于存放carry
            }
            cur = cur->next;
        }
        //最后反转链表,返回
        head = reverseList(head);
        return head;
        
    }
};

补充:206.反转链表(双指针法)

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

在这里插入图片描述

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

在这里插入图片描述

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

提示:

  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000

题解:206. 反转链表 - 力扣(LeetCode)

在这里插入图片描述

完整版

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* cur = head;
        ListNode* pre = nullptr;//pre是cur的前一个节点,也是反转之后当前节点需要指向的节点
        while(cur!=nullptr){
            ListNode* temp=cur->next;
            cur->next=pre;
            pre=cur;//下一个节点需要指向当前节点
            cur=temp;//cur访问下一个节点
        }
        return pre;
    }
};

在这里插入图片描述

2817.限制条件下元素之间的最小绝对差(cpp不知道为什么超时了,java可以)

给你一个下标从 0 开始的整数数组 nums 和一个整数 x

请你找到数组中下标距离至少为 x 的两个元素的 差值绝对值最小值

换言之,请你找到两个下标 ij ,满足 abs(i - j) >= xabs(nums[i] - nums[j]) 的值最小。

请你返回一个整数,表示下标距离至少为 x 的两个元素之间的差值绝对值的 最小值

示例 1:

输入:nums = [4,3,2,4], x = 2
输出:0
解释:我们选择 nums[0] = 4 和 nums[3] = 4 。
它们下标距离满足至少为 2 ,差值绝对值为最小值 0 。
0 是最优解。

示例 2:

输入:nums = [5,3,2,10,15], x = 1
输出:1
解释:我们选择 nums[1] = 3 和 nums[2] = 2 。
它们下标距离满足至少为 1 ,差值绝对值为最小值 1 。
1 是最优解。

示例 3:

输入:nums = [1,2,3,4], x = 3
输出:3
解释:我们选择 nums[0] = 1 和 nums[3] = 4 。
它们下标距离满足至少为 3 ,差值绝对值为最小值 3 。
3 是最优解。

提示:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^9
  • 0 <= x < nums.length

本题用java解法通过,但是cpp同样的写法,不知道为啥超时了。

思路是维护前面0i是个有序的序列,这样就可以用二分查找0i中和j最接近的元素

但是java中没有既可以自动排序,又可以用下标取的数据类型。所以就自己用二分维护了一个有序列表,就是每次来一个新元素i,用二分查找它应该放在哪个位置。有序序列就是 0 ~ i 中元素排序之后的结果。

class Solution {
    public int minAbsoluteDifference(List<Integer> nums, int x) {
        int n = nums.size(), ans = Integer.MAX_VALUE;
        List<Integer> ls = new ArrayList();         // 维护前面元素的有序序列(升序)
        for (int i = 0, j = x; j < n; ++i, ++j) {
            // 将nums[i]加入有序序列ls,使用二分查找寻找nums[i]应该插入的位置。
            int l = 0, r = ls.size(), v = nums.get(i);
            while (l < r) {
                int mid = l + r >> 1;
                if (ls.get(mid) <= v) l = mid + 1;
                else r = mid;
            }
            ls.add(l, v);
            
            // 使用二分查找寻找前面序列中最后一个<=nums[j]的元素
            l = 0;
            r = ls.size() - 1;
            v = nums.get(j);
            while (l < r) {
                int mid = l + r + 1 >> 1;
                if (ls.get(mid) > v) r = mid - 1;
                else l = mid;
            }
            // 使用和nums[j]最接近的元素更新答案
            ans = Math.min(ans, Math.abs(v - ls.get(l)));
            if (l + 1 < ls.size()) ans = Math.min(ans, Math.abs(ls.get(l + 1) - v));
        }
        return ans;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/960974.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

每秒百万级高效C++异步日志实践

一个高效可拓展的异步C日志库&#xff1a;RING LOG&#xff0c;本文分享了了其设计方案与技术原理等内容 详细代码见github路径&#xff1a;点击打开链接 导论 同步日志与缺点 传统的日志也叫同步日志&#xff0c;每次调用一次打印日志API就对应一次系统调用write写日志文件…

国际音标学习笔记

目录 1.单元音2.双元音3.辅音4.音节5.自然拼读法则5.1辅音字母的音标 1.单元音 我觉得单纯的音标并不好记住&#xff0c;所以就跟着老师整&#xff0c;根据单词记住音标的发音&#xff0c;以下是我的理解 音标对应的单词汉化iis衣əer饿ɔorigin奥u/ʊwoman五ʌart啊eanything哎…

哪个视觉语言模型更优?InstructBLIP、MiniGPT-4?全面评估基准LVLM-eHub告诉你

夕小瑶科技说 原创 作者 | 王思若 LLaMA、GPT-3等大型语言模型实现了对自然语言强大的理解和推理能力&#xff0c;为AI社区构筑了强大的语言基座模型。进而&#xff0c;继续迭代的GPT-4&#xff0c;更是赋予了模型处理图像的视觉能力。 如今&#xff0c;构建强大的多模态模型…

有源医疗器械技术要求编写要求之附录内容

目录 一、附录A中主要安全特征内容 二、附录内容简介 1、按防电击类型分类: 2、按防电击的程度分类: 3.按对进液的防护程度进行分类: 4.按在与空气混合的易燃麻醉气或与氧或氧化亚氮混合的易燃麻醉气况下使用时的安全程度分类: 6.设备的额定电压和频率 7.设备的输入功率…

QT 发布软件基本操作

一、配置环境变量 找到Qt安装时的bin目录的路径&#xff1a;D:\Qt\Qt5.14.2\5.14.2\mingw73_64\bin&#xff0c;将目录拷贝至下述环境变量中。 打开计算机的高级系统设置 选中环境变量-->系统变量-->Path 点击编辑-->新建-->粘贴 二、生成发布软件的可执行程序 …

【Python从入门到进阶】34、selenium基本概念及安装流程

接上篇《33、使用bs4获取星巴克产品信息》 上一篇我们介绍了如何使用bs4来解析星巴克网站&#xff0c;获取其产品信息。本篇我们来了解selenium技术的基础。 一、什么是selenium&#xff1f; Selenium是一种用于自动化Web浏览器操作的开源工具。它提供了一组API&#xff08;应…

SpringBoot——整合Mongodb

简单介绍 Mongdb是一个开源&#xff0c;高性能&#xff0c;无模式的文档型数据库&#xff0c;NoSQL数据库产品中的一种&#xff0c;是最像关系型数据库的非关系型数据库。 使用场景 用户数据 存储位置&#xff1a;数据库特征&#xff1a;永久性存储&#xff0c;修改频率极低游…

【C++】C++ 引用详解 ⑩ ( 常量引用案例 )

文章目录 一、常量引用语法1、语法简介2、常引用语法示例 二、常量引用语法1、int 类型常量引用示例2、结构体类型常量引用示例 在 C 语言中 , 常量引用 是 引用类型 的一种 ; 借助 常量引用 , 可以将一个变量引用 作为实参 传递给一个函数形参 , 同时保证该值不会在函数内部被…

可观测性用观测云,观测云护航「杭州亚运会」

2023 年亚洲运动会定于 2023 年 9 月 23 日至 10 月 8 日在中国杭州举办&#xff0c;这是在党的二十大召开后&#xff0c;我国疫情防控措施优化调整后举办的最大规模、最高水平的国际综合性运动会&#xff0c;意义十分重大。杭州亚组委以「举办一届史上最成功的亚运会」为工作目…

【0901作业】QTday3 对话框、发布软件、事件处理机制,使用文件相关操作完成记事本的保存功能、处理键盘事件完成圆形的移动

目录 一、思维导图 二、作业 2.1 使用文件相关操作完成记事本的保存功能 2.2 处理键盘事件完成圆形的移动 一、思维导图 二、作业 2.1 使用文件相关操作完成记事本的保存功能 void Widget::on_saveBtn_clicked() {QString filename QFileDialog::getSaveFileName(this,&…

MySQL数据库学习【进阶篇】

MySQL数据库学习进阶篇 MySQL进阶篇已经更新完毕&#xff0c;点击网址查看&#x1f449;&#xff1a;MySQL数据库进阶篇

【点击checkbox复选框,显示or隐藏某区域】

功能&#xff1a; 1. 选中复选框&#xff0c;显示隐藏的区域&#xff1b; 2. 取消选中&#xff0c;再隐藏该显示的区域。 方法1&#xff1a;在layui jquery框架下 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta char…

接口测试系列 —— 什么是接口测试?

接口测试系列 为什么要做这个事情&#xff1f; 对自己过往在接口测试上的经验&#xff0c;写一个小结的系列文章&#xff0c;是一个系统性的思考和知识构建。发布的同时&#xff0c;也是希望获得更多感兴趣的同学的意见和反馈&#xff0c;可以把这个部分做的更好。 接口测试概…

充电比加油还快?一秒一公里,全液冷超充项目试点,5 年全覆盖?

华为中国数字能源旗舰峰会广西站在桂林举行&#xff0c;标志着桂林在数字能源领域的迈进。与此同时&#xff0c;桂林市和华为数字能源展开了合作&#xff0c;启动了全液冷超充示范项目&#xff0c;为城市的电动车充电基础设施添砖加瓦。 根据华为数字能源技术有限公司副总裁何波…

如何解决微信收款异常问题

一、自查原因 当您遇到微信收款异常问题时&#xff0c;首先需要了解异常的原因。可能的原因包括违反微信支付相关规定、存在异常交易行为、账户安全问题等。了解原因后&#xff0c;您可以采取相应的措施进行处理。 二、联系客服 您可以通过微信支付官方客服渠道咨询具体的问题&…

Is f(z)=1/z truly an analytic function

https://math.stackexchange.com/questions/755566/is-fz-1-z-truly-an-analytic-function

react快速开始(三)-create-react-app脚手架项目启动;使用VScode调试react

文章目录 react快速开始(三)-create-react-app脚手架项目启动&#xff1b;使用VScode调试react一、create-react-app脚手架项目启动1. react-scripts2. 关于better-npm-runbetter-npm-run安装 二、使用VScode调试react1. 浏览器插件React Developer Tools2. 【重点】用 VSCode …

Mediasoup在node.js下多线程实现

mediasoup基于socket.io的交互消息来完成join-room的请求过程。Join的过程&#xff0c;实际就是获取stream的过程&#xff0c;也就是视频加载时间(video-load-speed)。在RTMP系统&#xff0c;视频加载时间是秒开。Mediasoup给出的第一个frame是I-frame&#xff0c;但由于交互的…

web服务基础以及简单的站点应用部署

一、 简述静态网页和动态网页的区别。 静态网页&#xff1a; 优势&#xff1a; ①访问的效率比较高 ②网页内容是固定不变的&#xff0c;因此&#xff0c;容易被搜索引擎收录 ③网页程序在用户浏览器端解析&#xff0c;当客户端向服务器请求数据时&#xff0c;服务器会直接从磁…

2001-2021年中国城市分产业创新指数(574万+)

2001-2021年中国城市分产业创新指数&#xff08;574万&#xff09; 1、时间&#xff1a;2001-2021年 2、来源&#xff1a;中国城市和产业创新力报告 3、指标&#xff1a;包括城市创新指数、产业创新指数、城市-产业创新指数 4、整理方式&#xff1a; 整理方式是基于国家知…