剑指offer:从尾到头打印链表
问题描述:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
解法:栈 a=[] a.append() a.pop() a.pop(0)
时间复杂度:O(n)
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
node = []
while listNode:
node.append(listNode.val)
listNode = listNode.next
return node[::-1]
剑指offer:链表中倒数第k个结点
问题描述:输入一个链表,输出该链表中倒数第k个结点
解法:两个指针,距离为k,当走在前面的指针指向None,遍历结束,返回走在后面的指针
时间复杂度:O(n)
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
# 指针头结点为空,k小于等于0
if head is None or k <= 0:
return None
p_end = head
p_res = head
for i in range(k):
# p_end从头结点开始,最大移动步数为节点个数,此时p_end指向None
if p_end:
p_end = p_end.next
# 链表没有k个结点
else:
return None
# 当p_end指向None时,循环结束
while p_end:
p_end = p_end.next
p_res = p_res.next
return p_res
剑指offer:反转链表
问题描述:输入一个链表,反转链表后,输出新链表的表头
解法:三个指针,pre-指向前一个结点,cur-当前结点,nex-保存当前结点曾经指向的位置
时间复杂度:O(k)
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
if pHead is None or pHead.next is None:
return pHead
pre = None
cur = pHead
while cur:
nex = cur.next
cur.next = pre
pre = cur
cur = nex
return pre
剑指offer:合并两个排序的链表
问题描述:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则
解法:递归的方式,返回链表1和2中指针指向的较小的值
时间复杂度:O(n)
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
if pHead1 is None:
return pHead2
elif pHead2 is None:
return pHead1
if pHead1.val <= pHead2.val:
head = pHead1
head.next = self.Merge(pHead1.next, pHead2)
else:
head = pHead2
head.next = self.Merge(pHead1, pHead2.next)
return head
剑指offer:复杂链表的复制
问题描述:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head
解法:先克隆节点并且 A’ 链接到 A 后面,然后复制克隆节点指向对应的克隆节点,最后拆分成两个链表
时间复杂度:O(n)
# -*- coding:utf-8 -*-
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# 1 创建克隆节点
node = pHead
if not node:
return None
while node:
clone = RandomListNode(node.label)
clone.next = node.next
node.next = clone
node = clone.next
# 2 克隆节点指向克隆节点
node = pHead
while node:
clone = node.next
if node.random:
clone.random = node.random.next
node = clone.next
# 3 长链表拆分为两个链表
node = pHead
if node:
clone_head = clone = node.next
node.next = clone.next
node = node.next
while node:
clone.next = node.next
clone = clone.next
node.next = clone.next
node = node.next
return clone_head
leetcode:141. 环形链表
问题描述:给定一个链表,判断链表中是否有环
解法:边界条件是没有元素or只有一个元素,都无法构成环形。快指针领先一个位置,且速度快,如果不是环形会先到达终点。慢指针每次移动一步,而快指针每次移动两步。如果慢指针追上了快指针,说明是环形数组。
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
# 没有元素or只有一个元素,都无法构成环形
if not head or not head.next:
return False
# 快指针在前面一步
k1 = head
k2 = head.next
# 慢指针每次移动一步,而快指针每次移动两步
while k1 != k2:
# 快指针领先一个位置,且速度快,如果不是环形会先到达终点
if k2 is None or k2.next is None:
return False
k1 = k1.next
k2 = k2.next.next
return True
剑指offer:两个链表的第一个公共结点
问题描述:输入两个链表,找出它们的第一个公共结点。
解法:
思路一:把两个链表放入两个栈里,找到最后一个相同的结点。注意公共结点可能在某一个链表的开始!
思路二:遍历链表的长度,长度差为k,长链表从k位置开始走,找到第一个公共结点
时间复杂度:O(m+n)
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# 思路一:把两个链表放入两个栈里,找到最后一个相同的结点
if not pHead1 or not pHead2:
return
stack1 = []
stack2 = []
while pHead1:
stack1.append(pHead1)
pHead1 = pHead1.next
while pHead2:
stack2.append(pHead2)
pHead2 = pHead2.next
# 提前保存原始链表长度
length1 = len(stack1)
length2 = len(stack2)
node1 = []
node2 = []
while node1 == node2 and stack1 and stack2:
node1.append(stack1.pop())
node2.append(stack2.pop())
if len(node1) <= 1 and node1 != node2:
return
if node1 == node2:
return node1[-1]
else:
return node1[-2]
# 思路二:遍历链表的长度,长度差为k,长链表从k位置开始走,找到第一个公共结点
if not pHead1 or not pHead2:
return
dis1 = 0
dis2 = 0
node1 = pHead1
node2 = pHead2
# 计算第一个链表的长度
while node1:
dis1 += 1
node1 = node1.next
# 计算第二个链表的长度
while node2:
dis2 += 1
node2 = node2.next
# 较长链表先走k步,k=长度差
if dis1 > dis2:
k = dis1 - dis2
while k:
k -= 1
pHead1 = pHead1.next
else:
k = dis2 - dis1
while k:
k -= 1
pHead2 = pHead2.next
# 同时遍历,找到第一个相同的结点
while pHead1 != pHead2:
pHead1 = pHead1.next
pHead2 = pHead2.next
return pHead2
leetcode:
问题描述:
解法:
时间复杂度:
剑指offer:
问题描述:
解法:
时间复杂度: