剑指Offer 链表类题目集合

从尾到头打印链表

刷题链接

https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035
题目描述
在这里插入图片描述

思路一
我的第一想法是可以遍历链表,将每个节点的值存入数组中,然后将数组进行反转。

在这里插入图片描述

复杂度分析

时间复杂度:O(n)。正向遍历一遍链表。
空间复杂度:O(n)。额外使用一个数组存储链表中的每个节点。

python3

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param listNode ListNode类 
# @return int整型一维数组
#
class Solution:
    def printListFromTailToHead(self , listNode: ListNode) -> List[int]:
        res = []
        while listNode:
            res.append(listNode.val)
            listNode = listNode.next
        return res[::-1]

C++

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
    
    
public:
    vector<int> printListFromTailToHead(ListNode* head) {
    
    
        vector<int> result;
        ListNode* current = head;
        while (current != nullptr) {
    
    
            result.push_back(current->val);
            current = current->next;
        }
        reverse(result.begin(), result.end());
        return result;
    }   
};

反转链表

刷题链接
https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca

题目描述
在这里插入图片描述

思路一
采用双指针迭代,在遍历链表时,将当前节点的next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。
在这里插入图片描述

复杂度分析

时间复杂度:O(n),正向遍历一遍链表。
空间复杂度:O(1),常数空间复杂度。

python3

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @return ListNode类
#
class Solution:
    def ReverseList(self , head: ListNode) -> ListNode:
        # write code here
        pre , cur = None ,head
        while cur:
            # 暂存后继节点 cur.next
            tmp = cur.next
            # 修改 next 引用指向
            cur.next = pre
            # pre 暂存 cur
            pre = cur
            # cur 访问下一节点
            cur = tmp
        return pre

C++

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
    
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    ListNode* ReverseList(ListNode* head) {
    
    
        ListNode *cur = head,*pre=nullptr;
        while(cur != nullptr){
    
    
            // 暂存后继节点 cur.next
            ListNode *tmp = cur->next;
            // 修改 next 引用指向
            cur->next = pre;
            // pre 暂存 cur
            pre = cur;
            // cur 访问下一节点
            cur = tmp;
        }
        return pre;
    }
};

合并两个排序的链表

刷题链接
https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337

题目描述
在这里插入图片描述
在这里插入图片描述

思路一
由于两个链表是递增的,可以使用双指针遍历两个链表,通过pHead1.val与pHead2.val的大小关系确定节点添加顺序,两节点指针交替前进,直至遍历完毕。
在这里插入图片描述

复杂度分析

时间复杂度:O(m+n),m,n 分别为两个链表的长度。
空间复杂度:O(1),常数空间复杂度。

python3

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param pHead1 ListNode类 
# @param pHead2 ListNode类 
# @return ListNode类
#
class Solution:
    def Merge(self , pHead1: ListNode, pHead2: ListNode) -> ListNode:
        cur = head = ListNode(0)
        while pHead1 and pHead2:
            if pHead1.val <= pHead2.val:
                cur.next, pHead1 = pHead1, pHead1.next
            else:
                cur.next, pHead2 = pHead2, pHead2.next
            cur = cur.next
        cur.next = pHead1 if pHead1 else pHead2
        return head.next

C++

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
    
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead1 ListNode类 
     * @param pHead2 ListNode类 
     * @return ListNode类
     */
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
    
    
        ListNode *cur = new ListNode(0);
        ListNode *head = cur;
        while(pHead1 != nullptr && pHead2 != nullptr){
    
    
            if(pHead1->val <= pHead2->val){
    
    
                cur->next = pHead1;
                pHead1 = pHead1->next;
            }
            else{
    
    
                cur->next = pHead2;
                pHead2 = pHead2->next;
            }
            cur = cur->next;
        }
        cur->next = pHead1 ? pHead1 : pHead2;
        return head->next;
    }
};

猜你喜欢

转载自blog.csdn.net/JulyLi2019/article/details/134837270