五月集训(第12天) —— 链表

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五月集训(第12天) —— 链表相关的知识,希望对你有一定的参考价值。

文章目录

前言

        此为《英雄算法联盟:算法集训》的内容,具体内容详见:知识星球:英雄算法联盟。加入星球后,即可享用星主 CSDN付费专栏 免费阅读 的权益。
        欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
        希望大家先自己思考,如果实在没有想法,再看下面的算法思路,如果有思路但是写不出来,可以参考朋友圈中其他人的代码,总有一款是适合你的,关注一下他,取其之长,补给之短。
        今天集训的内容是:链表
        前两题较为简单,第三题非常经典,常作为面试考题,第四题用到了栈的知识,如果对栈不是很了解,后天栈的内容讲解以后再来做也为时未晚。

一、练习题目

题目链接难度
1290. 二进制链表转整数★☆☆☆☆
237. 删除链表中的节点★☆☆☆☆
剑指 Offer II 024. 反转链表★★☆☆☆
1019. 链表中的下一个更大节点★★★☆☆

二、算法思路

1、二进制链表转整数

        (1)本题考察的就是链表的遍历,需要一点点数学知识。

class Solution 
public:
    int getDecimalValue(ListNode* head) 
        int sum = 0;
        while(head) 
            sum = sum * 2 + head->val;
            head = head->next;
        
        return sum;
    
;

2、删除链表中的节点

        (1)这是一道脑筋急转弯题;
        (2)我们知道删除一个链表结点,一定要知道它的前驱结点,但是这题不知道,所以我们可以进行一个取巧,将 给定结点下一个结点 的值赋值给 给定结点,然后删除 给定结点下一个结点,这样做就达到了删除 给定结点 的目的;

class Solution 
public:
    void deleteNode(ListNode* node) 
        node->val = node->next->val;
        node->next = node->next->next;
    
;

3、反转链表

        (1)如果链表长度为 n,则执行 n-1 次迭代,每次迭代将一个结点插入到链表头,此所谓 头插法
        (2)有一个常用技巧,就是生成一个 伪头结点,指向当前的头结点;
        (3)遍历链表的过程中,不断将遍历到的结点删除,插入到 伪头结点 的下一个结点。

class Solution 
public:
    ListNode* reverseList(ListNode* head) 
        if(head == nullptr) 
            return nullptr;
        
        ListNode *dummyhead = new ListNode();
        dummyhead->next = head;
        
            ListNode *pre = head, *now = head->next;
            while(now) 
                // 删除now
                pre->next = now->next;
                // 将now插入dummyhead的下一个
                now->next = dummyhead->next;
                dummyhead->next = now;
                // 更新 now
                now = pre->next;
            
        
        return dummyhead->next;
    
;

4、链表中的下一个更大节点

        (1)如果你没有学过 ,可以暂时先跳过此题;
        (2)维护一个单调不降的栈;
        (3)遍历链表,每次将 链表元素栈顶元素 进行比较,如果它比栈顶元素大,则栈顶元素的下一个更大元素就找到了,记录下来,弹出栈顶,继续判断,直到找不到为止;
        (4)然后将 链表元素 入栈;
        (5)最后返回记录的结果即可。

class Solution 
public:
    vector<int> nextLargerNodes(ListNode* head) 
        // 维护一个单调不增的栈
        stack< pair<int, int> > stk;
        int i;
        vector<int> ans;
        for(i = 0; i < 10000; ++i) 
            ans.push_back(-1);
        
        i = 0;
        while(head) 
            while(!stk.empty() && head->val > stk.top().first) 
                int index = stk.top().second;
                ans[index] = head->val;
                stk.pop();
            
            stk.push( pairhead->val, i );
            head = head->next;
            i++;
        
        while(!stk.empty()) 
            int index = stk.top().second;
            stk.pop();
            ans[index] = 0;
        

        while(ans.size() > i) 
            ans.pop_back();
        
        return ans;
    
;

以上是关于五月集训(第12天) —— 链表的主要内容,如果未能解决你的问题,请参考以下文章

五月集训(第29天) —— 分而治之

五月集训(第18天) —— 树

五月集训(第14天) —— 栈

五月集训(第24天) —— 线段树

五月集训(第31天) —— 状态压缩

五月集训(第25天) —— 树状数组