1. 链表中环的入口节点
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路一:用哈希表存已经遍历过的节点,O(1)复杂度查找,如果再次遇到就是环入口
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def EntryNodeOfLoop(self, pHead): # 用哈希表存遍历过的节点,重复的节点为环入口 if pHead is None or pHead.next is None: return None hashmap = set() p = pHead while p: if p in hashmap: return p hashmap.add(p) p = p.next
思路二:快慢指针
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def EntryNodeOfLoop(self, pHead): # 快慢指针;如果有环,快指针会追上慢指针;再分别从头节点和快慢指针相遇点向后,相遇的节点为环入口 if pHead is None or pHead.next is None: return None slow = pHead fast = pHead while fast: # 找快慢相遇点 slow = slow.next fast = fast.next.next if slow == fast: break slow = pHead # 找环入口 while slow != fast: slow = slow.next fast = fast.next return slow
2. 删除链表中重复的节点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
思路:需要一个pre作为p的前驱节点,如果遇到重复节点就一直向后遍历到不重复的节点,pre指过去即可。再往后遍历之前需要把p退回到pre,因为后面还是有可能出现和pre重复的节点。特别注意从头节点就开始重复的情况,需要把pHead指向不重复节点。
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def deleteDuplication(self, pHead): # write code here if pHead is None or pHead.next is None: return pHead pre = None # 记录p前面的节点 p = pHead while p: nextp = p.next if nextp and nextp.val == p.val: # 需要删除节点 sameVal = p.val # 向后一直找到不相同节点 pNeedDel = p # 要么从p开始重复到最后,pNeedDel为None;要么pNeedDel指向下一个不重复的节点 while pNeedDel and pNeedDel.val == sameVal: pNeedDel = pNeedDel.next if pre is None: # 如果pre还是None,说明从头节点开始一直重复,头节点要指向下一个不重复节点 pHead = pNeedDel p = pHead # 继续向后遍历,pre还是None就行了 else: # 如果是从头节点后面的节点开始重复,pHead不用变 pre.next = pNeedDel # 删除从p开始的重复节点 p = pre # 要退到开始重复的上一个节点,后面可能出现与pre重复的节点 else: # 不需要删除节点,向后遍历 pre = p p = nextp return pHead
3. 从尾到头打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
思路一:递归
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListFromTailToHead(self, listNode): # write code here if listNode is None: return [] if listNode.next is None: # 如果只有一个节点 return [listNode.val] return self.printListFromTailToHead(listNode.next) + [listNode.val] # 后面所有节点值的倒序list + [当前节点值]
思路二:list保存,逆序返回
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListFromTailToHead(self, listNode): # write code here res = [] p = listNode while p: res.append(p.val) p = p.next return res[::-1]
思路三:利用list的操作性质
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListFromTailToHead(self, listNode): # write code here if listNode is None: return [] if listNode.next is None: return [listNode.val] res = [listNode.val] p = listNode.next while p: res = [p.val] + res p = p.next return res
思路四:利用栈的先进后出
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListFromTailToHead(self, listNode): # write code here if listNode is None: return [] if listNode.next is None: return [listNode.val] res = [] p = listNode while p: res.insert(0, p.val) p = p.next return res