栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

剑指offer刷题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

剑指offer刷题

剑指offer刷题 链表 6 从尾到头打印链表

方法1:递归方式

//方法1.递归函数
class Solution {
public:
    //递归函数
    void recursion(ListNode* head, vector& res){
        if(head != nullptr){//边界条件
            //先往链表深处遍历
            recursion(head->next, res);
            //再填充到数组就是逆序
            res.push_back(head->val);
        }
    }
    vector printListFromTailToHead(ListNode* head) {
        vector res;
        //递归函数打印
        recursion(head, res);
        return res;
    }
};
//方法2.栈
class Solution {
public:
    vector reversePrint(ListNode* head) {
        vector res;
        stack s;
        while(head){
            //入栈
            s.push(head->val);
            head=head->next;
        }
        while(!s.empty()){
            //出栈
            res.push_back(s.top());
            s.pop();
        }
        return res;
    }
};
24 反转链表 25 合并两个排序的链表
 //方法1递归函数
class Solution {
public:
    
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        //当一个链表递归到尾部时,返回另一个还未递归到尾部的链表
        if(!l1){           
            return l2;
        }
        if(!l2){
            return l1;
        }
        if(l1->val>l2->val){
            l2->next=mergeTwoLists(l1,l2->next);
            return l2;
        }
        l1->next=mergeTwoLists(l1->next,l2);
        return l1;
    }
};
//方法2迭代方法
class Solution {
public:
    
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        //设置dummy伪头结点(哨兵节点)
        ListNode*dummy=new ListNode(0),*node=dummy;
        while(l1&&l2){
            if(l1->val>l2->val){
                node->next=l2;
                l2=l2->next;
            }
            else{
                node->next=l1;
                l1=l1->next;
            }
            //更新node
            node=node->next;
        }
        //node下一跳接不是尾节点的链表
        node->next=l1?l1:l2;
        return dummy->next;
    }
};
52 两个链表的第一个公共结点

链表 headA 和headB 的长度分别是 m 和 n。假设链表headA 的不相交部分有 a 个节点,链表headB 的不相交部分有 b 个节点,两个链表相交的部分有 c 个节点,则有 a+c=m,b+c=n。

  • 如果 a=b,则两个指针会同时到达两个链表的第一个公共节点,此时返回两个链表的第一个公共节点;
  • 如果 a ≠ neq ​=b,则指针pA 会遍历完链表 headA,指针pB 会遍历完链表headB,两个指针不会同时到达链表的尾节点,然后指针 pA 移到链表headB 的头节点,指针pB 移到链表headA 的头节点,然后两个指针继续移动,在指针pA 移动了a+c+b 次、指针pB 移动了 b+c+a 次之后,两个指针会同时到达两个链表的第一个公共节点,该节点也是两个指针第一次同时指向的节点,此时返回两个链表的第一个公共节点。
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        ListNode* l1=pHead1,* l2=pHead2;
        while(pHead1!=pHead2){         
            pHead1=pHead1?pHead1->next:l2;
            pHead2=pHead2?pHead2->next:l1;
        }
        return pHead1;
    }
};
23 链表中环的入口结点

对于1.链表找环路2.倒数最后k个节点的问题,有一个通用的解法——快慢指针(Floyd 判圈法)。
概括一下:
根据:

  • f=2s (快指针每次2步,路程刚好2倍)
  • f = s + nb (相遇时,刚好多走了n圈)

推出:s = nb从head结点走到入环点需要走 : a + nb, 而slow已经走了nb,那么slow再走a步就是入环点了。如何知道slow刚好走了a步? 从head开始,和slow指针一起走,相遇时刚好就是a步

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        ListNode* fast=pHead,*slow=pHead;
//         if(!fast) return fast;
//         while(fast->next&&fast->next->next){
//             fast=fast->next->next;
//             slow=slow->next;
//             if(fast==slow) break;
//         }
//         if(!fast->next||!fast->next->next) return NULL;
        //简化代码
        do{
            if(!fast||!fast->next) return nullptr;
            fast=fast->next->next;
            slow=slow->next;
        }while(fast!=slow);
        fast=pHead;
        while(fast!=slow){
            fast=fast->next;
            slow=slow->next;
        }
        return fast;
    }
};
22 链表中倒数最后k个结点

快慢指针:
快慢指针的思想。我们将第一个指针fast 指向链表的第k+1 个节点,第二个指针slow 指向链表的第一个节点,此时指针fast 与slow 二者之间刚好间隔 k 个节点。此时两个指针同步向后走,当第一个指针fast 走到链表的尾部空节点时,则此时slow 指针刚好指向链表的倒数第k个节点。

  • 我们首先将fast 指向链表的头节点,然后向后走 k 步,则此时 fast 指针刚好指向链表的第k+1 个节点。
  • 我们首先将slow 指向链表的头节点,同时 slow 与fast 同步向后走,当 fast 指针指向链表的尾部空节点时,则此时返回 slow 所指向的节点即可。
class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        ListNode* fast=head,*slow=head;
        for(int i=0;i
            if(!fast) return nullptr;
            fast=fast->next;
        }
        while(fast){
            fast=fast->next;
            slow=slow->next;
        }
        return slow;
    }
};
35 复杂链表的复制

参考LeetCode题解

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(!head) return nullptr;
        Node* cur=head;
        unordered_map hash;
        while(cur){
            hash[cur] = new Node(cur->val);
            cur=cur->next;
        }
        cur=head;
        while(cur){
            hash[cur]->next=hash[cur->next];
            hash[cur]->random=hash[cur->random];
            cur=cur->next;
        }
        return hash[head];
    }
};
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/929283.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号