剑指offer 链表题最佳解汇总 Python
来源:互联网 发布:淘宝怎么更改支付宝 编辑:程序博客网 时间:2024/05/21 03:20
面试题5: 从尾到头打印链表
输入一个链表,从尾到头打印链表每个节点的值。
思路:
class Solution: # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListFromTailToHead(self, listNode): l = [] # 直接遍历一遍链表保存结果到list中,再返回倒序的list即可 while listNode: l.append(listNode.val) listNode = listNode.next return l[::-1]
面试题15:链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点。
思路:个人总结最佳算法,先计算链表的长度,然后计算找到倒数第k个需要几次循环,并判断其中关系。最后用for循环,不断将指针指向下一个节点,即为所求。
# -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution: def FindKthToTail(self, head, k): len_node = 0 temp = head while temp: temp = temp.next len_node += 1 run_times = len_node - k if run_times < 0 or k < 0: return for i in range(run_times): head = head.next return head
面试题16:反转链表
输入一个链表,反转链表后,输出链表的所有元素。
思路:定义两个变量,分别保存前指针和后指针。
# -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution: # 返回ListNode def ReverseList(self, pHead): if not pHead: return None # 当前节点是pHead,Pre为当前节点的前一节点,Next为当前节点的下一节点 # 需要pre和next的目的是让当前节点从pre->head->next1->next2变成pre<-head next1->next2 # 即pre让节点可以反转所指方向,但反转之后如果不用next节点保存next1节点的话,此单链表就此断开了 # 所以需要用到pre和next两个节点 # 1->2->3->4->5 # 1<-2<-3 4->5 Pre = None Next = None while pHead: Next = pHead.next # 保存当前结点的next指针,方便反转第一次后,在链表断开的情况下,依然找到原来的下一个结点 pHead.next = Pre # 反转链表,将当前结点的next指针指向前一个结点 Pre = pHead # 保存当前结点,更新Pre,方便下一次调用 pHead = Next # 让pHead按原来顺序走到第二个结点 return Pre
面试题17:合并两个排序的链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路:
# -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution: # 返回合并后列表 def Merge(self, pHead1, pHead2): merged = None # 当pHead1为空时,返回pHead2 if not pHead1: return pHead2 # 当pHead2为空时,返回pHead1 if not pHead2: return pHead1 # 第一个链表中的第一个点小于第二个链表第一个点,那么merged第一个点就是pHead1的第一个点 # 对于他的next,继续执行递归 if pHead1.val < pHead2.val: merged = pHead1 merged.next = self.Merge(pHead1.next, pHead2) # 第一个链表中的第一个点大于第二个链表第一个点,那么merged第一个点就是pHead1的第一个点 # 对于他的next,继续执行递归 else: merged = pHead2 merged.next = self.Merge(pHead1, pHead2.next) return merged
面试题26:复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
思路:
# -*- coding:utf-8 -*-# class RandomListNode:# def __init__(self, x):# self.label = x# self.next = None# self.random = Noneclass Solution: # 返回 RandomListNode def Clone(self, pHead): if not pHead: return pHead # 开辟一个新结点 copy = RandomListNode(pHead.label) copy.next = pHead.next copy.random = pHead.random # 递归剩余结点 copy.next = self.Clone(pHead.next) return copy
面试题37:两个链表的第一个公共结点
输入两个链表,找出它们的第一个公共结点。
思路:
# -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution: def FindFirstCommonNode(self, pHead1, pHead2): # 最优解:O(m+n),比放到stack里面做,节省了空间 if not pHead1 or not pHead2: return None length1 = 0 length2 = 0 p1 = pHead1 p2 = pHead2 # 分别计算两个链表的长度 while p1: length1 += 1 p1 = p1.next while p2: length2 += 1 p2 = p2.next # 根据两个链表的长度,确定长、短链表和它们之间的长度之差 if length1 >= length2: step = length1 - length2 longList = pHead1 shortList = pHead2 else: step = length2 - length1 longList = pHead2 shortList = pHead1 # 让长链表先走step步 for i in range(0,step): longList = longList.next # 同时遍历两个链表,让他们不断指向next,并判断何时相等,相等时返回任一一个链表即可 while longList and shortList: if longList == shortList: return longList longList = longList.next shortList = shortList.next return None
面试题56:链表中环的入口结点
一个链表中包含环,请找出该链表的环的入口结点。
思路:
第一步,找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,p2每次走二步,直到p1==p2找到在环中的相汇点。
第二步,找环的入口。接上步,当p1==p2时,p2所经过节点数为2x,p1所经过节点数为x,设环中有n个节点,p2比p1多走一圈有2x=n+x; n=x;可以看出p1实际走了一个环的步数,再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2;此时p1指向环的入口。
# -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution: def EntryNodeOfLoop(self, pHead): if pHead ==None: return 1 if pHead.next==None or pHead.next.next==None: return None # 使用快慢指针,p每次走两步,q每次走一步 p = pHead.next.next q = pHead.next # 第一次循环,直到p和q相遇,p每次走两步,q每次走一步 while p!=q: p = p.next.next q = q.next if p.next == None or p.next.next ==None: return None # 第二次循环,直到p和q相遇,让快指针p回到开始的点,p和q每次都走一步 p = pHead while p!=q: p = p.next q = q.next return q
面试题57:删除链表中重复的结点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
思路:
方法一:
# -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution: def deleteDuplication(self, pHead): temp = [] # 先将pHead中所有结点的value全部放到temp列表中去 while head: temp.append(head.val) head = head.next result = ListNode(0) # 创建一个新的指针 head = result # 让head指向这个指针 for i in temp: if temp.count(i) == 1:# 对于temp中的元素,如果出现次数等于1就添加到head的next指针 head.next = ListNode(i) head = head.next return result.next # 最后返回result.next,这里用head是因为如果直接操作result最后result会指向最后一个指针无法返回需要的结果
方法二:
# -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution: def deleteDuplication(self, pHead): if not pHead: return None first = ListNode(0) # 生成一个头指针 last = first while pHead and pHead.next: if pHead.val == pHead.next.val: while pHead.next and pHead.val == pHead.next.val: pHead = pHead.next else: last.next = pHead # 删除链表中重复的结点 last = last.next pHead = pHead.next last.next = pHead return first.next
扩展:判断链表是否有环
思路:
# -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution: def hasCycle(self, pHead): if pHead ==None: return False if pHead.next==None or pHead.next.next==None: return False # 使用快慢指针,p每次走两步,q每次走一步 slow = pHead.next.next quick = pHead.next while slow.next and quick.next: if slow == quick: return True slow = slow.next.next quick = quick.next return False
- 剑指offer 链表题最佳解汇总 Python
- 剑指offer 二叉树与二叉搜索树最佳解汇总 Python
- 剑指offer文章汇总
- 剑指offer系列文章汇总
- 剑指offer题目汇总(一)
- 剑指offer题目汇总(二)
- 剑指offer题目汇总(三)
- 《剑指offer》之知识汇总
- 剑指offer题目思想汇总
- 剑指offer--python
- 剑指offer——滑动窗口的最大值_(非最佳解)
- 【剑指Offer学习】【所有面试题汇总】
- 剑指offer 面试题题目汇总
- [面试算法] 剑指Offer题目代码汇总
- 剑指offer--DP类题目汇总
- 【剑指Offer学习】【所有面试题汇总】
- 【剑指Offer学习】【所有面试题汇总】
- 剑指offer面试题汇总-Java实现
- 创建一个D3D11应用程序流程
- iPhone 8快速充电技术简介,苹果再也不能被安卓嘲笑充电慢
- 一直用PDO,PHP中操作MYSQL数据库常用函数还记得不
- S5PV210刷机方法
- MySQL explain执行计划解读
- 剑指offer 链表题最佳解汇总 Python
- 欧拉函数(或者容斥)-HDU5514
- 学习笔记:ES6之Promise
- Linux内核进程调度
- Redis集群方案大全
- 前端性能优化+CDN优化
- datagrid控制分页js代码
- JAVA设计模式之单例模式
- Solr的安装及配置