• 复习Day10:哈希表part03:41. 缺失的第一个正数、138. 随机链表的复制


    labuladong 题解思路

    之前的blog:https://blog.csdn.net/weixin_43303286/article/details/131797610?spm=1001.2014.3001.5501

    我用的方法是在leetcode再过一遍例题,明显会的就复制粘贴,之前没写出来就重写,然后从拓展题目中找题目来写。辅以Labuladong的文章看。然后刷题不用CLion了,使用leetcode自带模拟面试环境。

    哈希表章节的题目思路很清晰,主要是C++中的写法。

    41. 缺失的第一个正数

    给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
    
    请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
     
    
    示例 1:
    
    输入:nums = [1,2,0]
    输出:3
    示例 2:
    
    输入:nums = [3,4,-1,1]
    输出:2
    示例 3:
    
    输入:nums = [7,8,9,11,12]
    输出:1
     
    
    提示:
    
    1 <= nums.length <= 5 * 105
    -231 <= nums[i] <= 231 - 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    这里要求时间复杂度为O(n),所以没办法排序,如果不限制复杂度的话,我们可以将数组所有的数放入哈希表,随后从 1开始依次枚举正整数,并判断其是否在哈希表中,也可以从 1开始依次枚举正整数,并遍历数组,判断其是否在数组中。

    「真正」满足时间复杂度为 O(N)且空间复杂度为 O(1)的算法是不存在的,但是我们可以退而求其次:利用给定数组中的空间来存储一些状态。也就是说,如果题目给定的数组是不可修改的,那么就不存在满足时空复杂度要求的算法;但如果我们可以修改给定的数组,那么是存在满足要求的算法的。

    这题用到的技巧:使用数组本身做hashtable。

    我们将数组中所有小于等于 000 的数修改为 N+1N+1N+1;

    我们遍历数组中的每一个数 xxx,它可能已经被打了标记,因此原本对应的数为 ∣x∣|x|∣x∣,其中 ∣ ∣|,|∣∣ 为绝对值符号。如果 ∣x∣∈[1,N]|x| \in [1, N]∣x∣∈[1,N],那么我们给数组中的第 ∣x∣−1|x| - 1∣x∣−1 个位置的数添加一个负号。注意如果它已经有负号,不需要重复添加;

    在遍历完成之后,如果数组中的每一个数都是负数,那么答案是 N+1N+1N+1,否则答案是第一个正数的位置加 111。

    class Solution {
    public:
        int firstMissingPositive(vector<int>& nums) {
            int n = nums.size();
            for (int& num: nums) {
                if (num <= 0) {
                    num = n + 1;
                }
            }
            for (int i = 0; i < n; ++i) {
                int num = abs(nums[i]);
                if (num <= n) {
                    nums[num - 1] = -abs(nums[num - 1]);
                }
            }
            for (int i = 0; i < n; ++i) {
                if (nums[i] > 0) {
                    return i + 1;
                }
            }
            return n + 1;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    138. 随机链表的复制

    class Solution {
    public:
        Node* copyRandomList(Node* head) {
            if (head == nullptr) {
                return nullptr;
            }
            for (Node* node = head; node != nullptr; node = node->next->next) {
                Node* nodeNew = new Node(node->val);
                nodeNew->next = node->next;
                node->next = nodeNew;
            }
            for (Node* node = head; node != nullptr; node = node->next->next) {
                Node* nodeNew = node->next;
                nodeNew->random = (node->random != nullptr) ? node->random->next : nullptr;
            }
            Node* headNew = head->next;
            for (Node* node = head; node != nullptr; node = node->next) {
                Node* nodeNew = node->next;
                node->next = node->next->next;
                nodeNew->next = (nodeNew->next != nullptr) ? nodeNew->next->next : nullptr;
            }
            return headNew;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    【启扬方案】启扬安卓屏一体机在医疗自助服务终端上的应用解决方案
    笔试强训第十九天 (最长公共子串+汽水瓶)
    java时序图工具_Java进阶架构师之如何画好架构图?阿里大神手把手教你!
    我用Cypress做了前端自动化测试
    K-Means算法进行分类
    期货十三篇 第十一篇 分析篇
    科普:如何应用视觉显著性模型优化远控编码算法?
    vivo 网络端口安全建设技术实践
    一款好用的问卷调查工具要必备哪些功能特点?
    【深度学习21天学习挑战赛】备忘篇:模型复用——模型的保存与加载
  • 原文地址:https://blog.csdn.net/weixin_43303286/article/details/133590276