1.字符串的全排列
思路:
以abc为例,取出b,分别在a的前后插入b,可以得到ab,ba,然后再ab的每一个位置插入c,可以得到cab,acb,abc,对ba采取同样的操作。最终可以得到全排列的6种结果。代码如下:
#coding:utf-8
def insertChar(srcStr,Char): #将一个字符插入一个字符串中
dstStr=[]
for i in range(len(srcStr)+1):
dstStr.append(srcStr[:i]+Char+srcStr[i:])
return dstStr
def Permutation(str):
s_former=[str[0]]
i=1
while i<len(str): # i用来遍历整个字符串,控制循环结束
str_permutated=[] #用来保存每次插入单个字符后的字符串list
for s in s_former:
Char=str[i] # i用来选择插入字符串的字符
str_permutated.extend(insertChar(s,Char)) #将生成的全排列好的子串保存,下一次全排列使用
s_former=str_permutated
i+=1
return s_former
print Permutation('abc')
2.两链表的公共结点
方法一:将两链表的结点入栈,找第一个不相同的结点,返回该结点的下一个结点即可。代码如下:
#coding:utf-8
def findCommonNode(head1,head2):
st1=[] #两个栈用来存放两链表的结点
st2=[]
while head1:
st1.append(head1)
head1=head1.next
while head2:
st2.append(head2)
head2=head2.next
while st1 and st2:
top1=st1.pop()
top2=st2.pop()
if top1!=top2:
return top1.next
方法二:计算两个链表的长度差diff,让长链表先走diff个结点,然后两链表同时后移,第一个相同的结点即为公共结点。代码如下:
#coding:utf-8
def findCommonNode(head1,head2):
len1=len2=0 #记录两个链表的长度
tempHead1=head1
tempHead2=head2
while tempHead1:
tempHead1=tempHead1.next
len1+=1
while tempHead2:
tempHead2=tempHead2.next
len2+=1
if len1<len2: #始终让head1是较长的那个链表
head1,head2=head2,head1
diff=abs(len1-len2)
fast,slow=head1,head2
while diff: #较长的链表先走diff个结点
fast=fast.next
diff-=1
while fast!=slow:
fast=fast.next
slow=slow.next
return fast
3.找到链表环的入口
剑指offer上的思路:
第一步,判断链表是否存在环。利用快慢指针,快指针每次走两个结点,慢指针每次走一个结点。若存在环,则两指针会在环内相遇。
第二步:确定环中结点的数目。由于相遇时快慢指针均在环中,现在让慢指针不动,快指针每次移动一个结点,直到两指针相遇,记录下快指针走过的结点的数目LoopNumber。
第三步:让p1,p2两个指针均指向头节点,p1先走LoopNumber个结点,然后两结点同时移动,当两结点相遇时即为环的入口处。
代码如下:
def findLoop(head):
slow=fast=head
while fast: #判断链表是否有环
fast=fast.next.next
slow=slow.next
if not fast:
print "No loop!"
return None
if fast==slow: #快慢指针相遇,说明链表存在环
fast=fast.next
loopNumber=1
while fast!=slow: #确定环中结点的个数
fast=fast.next
loopNumber+=1
break
#当跳出该循环时快指针指向的结点和头结点距离环的入口结点距离相等。
#因此可以让两结点以相同的速度同时走,相遇处即为环的入口。
slow=head
while slow!=fast:
slow=slow.next
fast=fast.next
return slow
4.两个排序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。
请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。
示例 1:
nums1 = [1, 3] nums2 = [2] 中位数是 2.0
示例 2:
nums1 = [1, 2] nums2 = [3, 4] 中位数是 (2 + 3)/2 = 2.5
利用归并排序的思想,将前一半的数存到新数组中,返回中位数即可。代码如下:
#coding:utf-8
def findMedian(nums1,nums2):
medianList=[] #保存中位数及中位数之前的数
len1,len2=len(nums1),len(nums2)
ListLength=(len1+len2)//2+1 #新数组的长度
while ListLength:
#每次将两数组中值最小的数添加到新数组中
if nums1 and nums2:
medianList.append(nums1.pop(0)) if nums1[0]<nums2[0] else medianList.append(nums2.pop(0))
else:
if nums1:
medianList.append(nums1.pop(0))
elif nums2:
medianList.append(nums2.pop(0))
ListLength-=1
if (len1+len2)%2==1:
return float(medianList[-1])
else:
return (float(medianList[-1])+medianList[-2])/2