• 面试随缘刷题--链表专项


    leetcode no.2 两数相加

    • 两个逆序链表加和,只需要按位加,保留进位符,最后到两个空进位空结束
    • 记得每次结束以后让当前链表位指向下一位,处理的和被处理的都是
    • 要将结果头返回,所以要有一个专门的指针用来移位的
    • 前面判断条件是两个链表都非空&&
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            ListNode*ans=new ListNode(0);
            ListNode*realans=ans;
            int temp=0;
            while(l1!=NULL && l2!=NULL){
                ans->next=new ListNode((l1->val+l2->val+temp)%10);
                temp=(l1->val+l2->val+temp)/10;
                ans=ans->next;
                l1=l1->next;
                l2=l2->next;
            }
            while(l1!=NULL)
            {
                ans->next=new ListNode((l1->val+temp)%10);
                temp=(l1->val+temp)/10;
                l1=l1->next;
                ans=ans->next;
            }
            while(l2!=NULL)
            {
                ans->next=new ListNode((l2->val+temp)%10);
                temp=(l2->val+temp)/10;
                l2=l2->next;
                ans=ans->next;
            }
            if(temp!=0)
            ans->next=new ListNode(temp);
            return realans->next;
        }
    };
    View Code

     leetcode no.19 删除链表的倒数第N个节点

    • 双指针,让两个的距离为n-1
    • 注意考虑删除的是第一个元素的情况
    • pre指针用来删除的时候用,因此只要指针移动的时候存在就好了
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode*temp1=head;
            ListNode*temp2=head;
            ListNode*pre;
            for(int i=1;i<n;i++)
                temp2=temp2->next;
            if(temp2->next==NULL)
                return head->next;
            while(temp2->next!=NULL)
            {
                pre=temp1;
                temp1=temp1->next;
                temp2=temp2->next;
            }
            pre->next=temp1->next;
            return head;
        }
    };
    View Code

     leetcode no.21 合并两个有序链表

    • 两个不为空就比,为空就连上
    • 可以不新生成节点直接连原来的会更节省内存(因为不用新生成节点),面试学到的,看leetcode标程也是这么说的。。但那个结果显示就很奇怪。。不管了
    • 只有原地调整链表才是o1空间哦,多一个指针,不然反复新生成是要占用的
    • 两条原始链表并不需要保存头,因此可以直接移动指针,不用新加
    /**
     * 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* mergeTwoLists(ListNode* l1, ListNode* l2) {
            ListNode*temp1=l1;
            ListNode*temp2=l2;
            ListNode*ans=new ListNode(0);
            ListNode*realans=ans;
            while(temp1!=NULL && temp2!=NULL)
            {
                if(temp1->val<=temp2->val)
                {
                    ans->next=temp1;
                    temp1=temp1->next;
                    ans=ans->next;
                }
                else
                {
                    ans->next=temp2;
                    temp2=temp2->next;
                    ans=ans->next;
                }
            }
            if(temp1!=NULL)
                ans->next=temp1;
            if(temp2!=NULL)
                ans->next=temp2;
            return realans->next;
        }
    };
    View Code

     leetcode no.23 合并k个升序链表

    • 类似归并的思路(这个两个两个来再变多的思路叫分治法)
    • 本质上是两个两个合并,然后合成长的在两个合并,降低复杂度到log
    • 调用合并两个升序链表的代码
    • 每次步长是step*2,以二倍的速度增长
    • j每次从0开始,然后下一个j是跨越两倍步长的值,两倍哦!因为step代表的是,同组即将合并的两个之间的距离,那么第二个和下一组第一个也是这个距离,所以是两个,千万不要搞错然后反复合并浪费时间
    • 注意空vector,特判len==0 直接返回NULL
    • 每次保留在较小的下标对应链表中,节省空间哦
    /**
     * 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*mergetwo(ListNode*l1,ListNode*l2)
        {
            ListNode*temp1=l1;
            ListNode*temp2=l2;
            ListNode*ans=new ListNode(0);
            ListNode*realans=ans;
            while(l1 && l2)
            {
                if(l1->val<=l2->val)
                {
                    ans->next=l1;
                    l1=l1->next;
                    ans=ans->next;
                }
                else
                {
                    ans->next=l2;
                    l2=l2->next;
                    ans=ans->next;
                }
            }
            if(l1)
                ans->next=l1;
            if(l2)
                ans->next=l2;
            return realans->next;
        }
        ListNode* mergeKLists(vector<ListNode*>& lists) {
            int len=lists.size();
            if(len==0)
                return NULL;
            for(int step=1;step<=len;step=step*2)
            {
                for(int j=0;j<=len-1;j=j+step*2)
                {
                    if(j+step<=len-1)
                    lists[j]=mergetwo(lists[j],lists[j+step]);
                }
            }
            return lists[0];
        }
    };
    View Code

     leetcode no.24 两两交换链表中的节点

    • 前面加一个空节点,从空节点开始pre,之后两个一组如果都不为空就倒置
    • 两个点交换,就是哪个前面连着的新的更新好了,接下来就修改那个,注意最后是pre->next->next,不要手误
    • 返回的结果是空节点的下一个,不要直接返回head,那样会把修改后新的head节点漏掉
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        void change(ListNode*pre)
        {
            ListNode*temp=pre->next;
            pre->next=temp->next;
            temp->next=pre->next->next;
            pre->next->next=temp;
        }
        ListNode* swapPairs(ListNode* head) {
            ListNode*newHead=new ListNode(0);
            newHead->next=head;
            ListNode*pre=newHead;
            while(pre->next!=NULL && pre->next->next!=NULL)
            {
                change(pre);
                pre=pre->next->next;
            }
            return newHead->next;
        }
    };
    View Code
    时间才能证明一切,选好了就尽力去做吧!
  • 相关阅读:
    openmediavault 5.5.23 安装插件失败的解决方案
    qt下载地址
    qt 5.12 增加 mysql驱动
    选基金标准
    关注几个基金
    调仓的几个问题
    要读的书
    ubuntu 20.04 LTS 安装webmin
    set的常见用法
    斜率优化dp([HNOI2008]玩具装箱)
  • 原文地址:https://www.cnblogs.com/tingxilin/p/13586286.html
Copyright © 2020-2023  润新知