【剑指Offer专题】链表系列:从尾到头打印链表、反转链表、回文链表、合并两个排序的链表(C++和Python实现)... | 您所在的位置:网站首页 › Python打印*号金字塔 › 【剑指Offer专题】链表系列:从尾到头打印链表、反转链表、回文链表、合并两个排序的链表(C++和Python实现)... |
关注上方“深度学习技术前沿”,选择“星标公众号”, 资源干货,第一时间送达! 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1: 输入:head = [1,3,2]输出:[2,3,1] 1、思路通常,这种情况下,我们不希望修改原链表的结构。返回一个反序的链表,这就是经典的“后进先出”,我们可以使用栈实现这种顺序。每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,给一个新的链表结构,这样链表就实现了反转。 2、代码C++实现: /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/class Solution {public:vector reversePrint(ListNode* head) {stack result;vector reverse;ListNode* nodes = head;while(nodes !=NULL){result.push(nodes->val);nodes = nodes->next;}while(!result.empty()){reverse.push_back(result.top());result.pop();}return reverse;}}; Python实现: # -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution:def printListFromTailToHead(self, listNode):# write code hereresult = []while listNode:result.insert(0, listNode.val)listNode = listNode.nextreturn result 剑指Offer(十五):反转链表反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL 1、思路这个很简单,我们使用三个指针,分别指向当前遍历到的结点、它的前一个结点以及后一个结点。 在遍历列表时,将当前节点的 next 指针改为指向前一个元素. 2、代码C++: /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/class Solution {public:ListNode* reverseList(ListNode* head) {ListNode* pReversedHead = NULL;ListNode* pNode = head;ListNode* pPrev = NULL;while(pNode != NULL){ListNode* pNext = pNode->next;if(pNext == NULL){pReversedHead = pNode;}pNode->next = pPrev;pPrev = pNode;pNode = pNext;}return pReversedHead;}}; python: # Definition for singly-linked list.# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution:def reverseList(self, head: ListNode) -> ListNode:if not head or not head.next:return headlast = Nonewhile head:tmp = head.nexthead.next = lastlast = headhead = tmpreturn last LeetCode 234. 回文链表请判断一个链表是否为回文链表。 示例 1: 输入: 1->2输出: false 示例 2: 输入: 1->2->2->1输出: true 1、算法思路复制链表值到数组列表中。 使用双指针法判断是否为回文。 遍历链表将值复制到数组列表中。用 currentNode 指向当前节点。每次迭代向数组添加 currentNode.val,并更新 currentNode = currentNode.next,当 currentNode = null 则停止循环。 在 Python 中,很容易构造一个列表的反向副本,也很容易比较两个列表。因此最好使用双指针法来检查是否为回文。我们在起点放置一个指针,在结尾放置一个指针,每一次迭代判断两个指针指向的元素是否相同,若不同,返回 false;相同则将两个指针向内移动,并继续判断,直到相遇。 在编码的过程中,注意我们比较的是节点值的大小,而不是节点本身。正确的比较方式是:node_1.val == node_2.val。而 node_1 == node_2 是错误的。 2、复杂度分析时间复杂度:O(n),其中 n 指的是链表的元素个数。 第一步:遍历链表并将值复制到数组中,O(n)。 第二步:双指针判断是否为回文,执行了 O(n/2)次的判断,即 O(n)。 总的时间复杂度:O(2n) = O(n)。 空间复杂度:O(n),其中 n 指的是链表的元素个数,我们使用了一个数组列表存放链表的元素值。 3、代码实现:# Definition for singly-linked list.# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution:def isPalindrome(self, head: ListNode) -> bool:vals = []current_node = headwhile current_node is not None:vals.append(current_node.val)current_node = current_node.nextreturn vals == vals[::-1] 剑指Offer(十六):合并两个排序的链表输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 1、思路先判断输入的链表是否为空的指针。如果第一个链表为空,则直接返回第二个链表;如果第二个链表为空,则直接返回第一个链表。如果两个链表都是空链表,合并的结果是得到一个空链表。 两个链表都是排序好的,我们只需要从头遍历链表,判断当前指针,哪个链表中的值小,即赋给合并链表指针即可。使用递归就可以轻松实现。 2、代码实现C++: /*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public:ListNode* Merge(ListNode* pHead1, ListNode* pHead2){//判断指针是否为空if(pHead1 == NULL){return pHead2;}else if(pHead2 == NULL){return pHead1;}ListNode* pMergedHead = NULL;if(pHead1->val val){pMergedHead = pHead1;pMergedHead->next = Merge(pHead1->next, pHead2);}else{pMergedHead = pHead2;pMergedHead->next = Merge(pHead1, pHead2->next);}return pMergedHead;}}; Python: # -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution:# 返回合并后列表def Merge(self, pHead1, pHead2):# write code hereif not pHead1:return pHead2if not pHead2:return pHead1pMergeHead = Noneif pHead1.val -END- 推荐阅读: 【LeetCode】一文详解二叉树的三大遍历:前序、中序和后序(python和C++实现) 算法求职必备书籍-《剑指Offer》 你面试稳了!通关LeetCode刷题完整攻略,省时又高效 既然来了,给个在看可否!~ |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |