单链表排序
单链表的特点是不知道全长,只能从前往后遍历,如果用归并,就要找中点,怎么找呢,快慢指针,慢指针每次走一步,快指针每次走两步,当快指针走到头的时候刚好慢指针走了一半。
class ListNode(object):
def __init__(self,x):
self.val=x
self.next=None
class Solution(object):
def sortList(self,head):
if not head or not head.next:
return head
slow=head
fast=head
while fast.next and fast.next.next:
slow=slow.next
fast=fast.next.next
mid=slow.next
slow.next= None # 找到中点后截断
left=self.sortList(head)
right=self.sortList(mid)
return self.merge(left,right)
def merge(self,left,right):
dummy=ListNode(0)
p=dummy
while left and right:
if left.val>right.val:
p.next=right
right=right.next
p=p.next
else:
p.next=left
left=left.next
p=p.next
if left:
p.next=left
if right:
p.next=right
return dummy.next
顺便做了一下leecode的合并k个单链表
合并k个单链表
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
if len(lists)==0:
return None
if len(lists)==1:
return lists[0]
if len(lists)==2:
dummy=ListNode(0)
p=dummy
l1=lists[0]
l2=lists[1]
while l1 and l2:
if l1.val>l2.val:
p.next=l2
p=p.next
l2=l2.next
else:
p.next=l1
p=p.next
l1=l1.next
if l1:
p.next=l1
if l2:
p.next=l2
return dummy.next
mid=len(lists)//2
left_lists=lists[:mid]
right_lists=lists[mid:]
left=self.mergeKLists(left_lists)
right=self.mergeKLists(right_lists)
return self.mergeKLists([left,right])
爬N个楼梯M种爬法
先说一下简单的爬楼梯问题,n个楼梯有一次可以爬一个或者两个,问有多少种爬法,显然斐波那契数列递归法,f(n)=f(n-1)+f(n-2)。
def climstair(n):
if n<=2:
return n
return climstair(n-1)+climstair(n-2)
现在升级版本是,假设有m种爬法,n阶楼梯。直观的想还是f(n)=f(n-1)+f(n-2)+f(n-3)+…+f(n-m),但是问题来了,当n<m的时候怎么终止,n=1的时候是1, n=2的时候是,n=3的时候是4,n=m的时候呢?其实这是另外一个数列了,解决方法如下
def bossclimbstair(m,n):
dp={}
dp[0]=1
dp[1]=1
for ii in range(2,m+1):
dp[ii]=sum([dp[ii-xx] for xx in range(1,ii+1)])
if n==0:
return 0
if n<=m:
return dp[n]
return sum([climbstair(m,n-ii) for ii in range(1,m+1)])