剑指offer (C++版)分类整理(二):链表类

1.JZ3 从尾到头打印链表

题目描述:

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

思路一:如果是从尾到头打印链表,我们自然想到可以使用栈存储节点值,然后倒序打印。

class Solution {
   
public:
    vector<int> printListFromTailToHead(ListNode* head) {
   
        vector<int> result;
        stack<int> arr;
        ListNode* p=head;
        while(p!=NULL)
        {
   
            arr.push(p->val);
            p=p->next;
        }
        while(!arr.empty())
        {
   
            result.push_back(arr.top());
            arr.pop();
        }
        return result;
    }
};

思路二:可以原地反转链表,然后反转后的顺序打印链表。需要注意的是,原地反转链表需要借助额外两个节点指针,需要特别注意的是节点反转指针的顺序遵从“由后往前”的次序。

class Solution {
   
public:
    vector<int> printListFromTailToHead(struct ListNode* head) {
   
        vector<int> res;
        ListNode *cur=head;
        ListNode *pre=cur;
        if(head==NULL)
            return res;
        while(head->next!=NULL){
   
        	//将cur节点移到pre节点之前
            cur=head->next;
            head->next=cur->next;
            cur->next=pre;
            pre=cur;
        }
        while(cur){
   
            res.push_back(cur->val);
            cur=cur->next;
        }
        return res;
        
    }
};

2.JZ14 链表中倒数第k个结点

题目描述:

输入一个链表,输出该链表中倒数第k个结点。

思路一:暴力法
先遍历整个链表,统计节点个数n(从1开始),然后从头遍历链表,输出第n-k-1个节点就是结果。

思路二:双指针法
先让一个指针走上k步,此时当前指针距离链表尾部距离为n-k,然后让另一个指针从头开始两个指针同时走,当指针一到达尾部时,指针二距离尾部为n-(n-k)= k,即倒数第k个结点。

class Solution {
   
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
   
        //p1指针先遍历k个节点,pListHead再从头开始
        ListNode* p1=pListHead;
        for(int i=0;i<k;i++)
            if(!p1)
                return nullptr;
            else
                p1=p1->next;
        while(p1){
   
            p1=p1->next;
            pListHead=pListHead->next;
        }
        return pListHead;
    }
};

3.JZ15 反转链表 链表

题目描述:

输入一个链表,反转链表后,输出新链表的表头。

思路一:原地反转。与第一题非常类似,只是输出反转后的表头。

class Solution {
   
public:
    ListNode* ReverseList(ListNode* pHead) {
   
        if(pHead == NULL || pHead->next == NULL)
        {
   
            return pHead;
        }
        ListNode* pre = NULL;
        ListNode* after = NULL;
        while(pHead)
        {
   
            //此处顺序需要弄清楚,先后再前
            after = pHead->next; //after最多为空
            pHead->next = pre;
            pre = pHead;
            pHead = after;
        }
        return pre;
    }
};

思路二:使用栈存储结点,利用栈的先入后出顺序。与第一题非常类似,只是输出反转后的表头。

class Solution {
   
public:
    ListNode* ReverseList(ListNode* pHead) {
   
        if(pHead == NULL || pHead -> next == NULL)
            return pHead;
        ListNode* p = pHead;
        stack<ListNode
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值