1.字符串的全排列
思路:
以abc为例,取出b,分别在a的前后插入b,可以得到ab,ba,然后再ab的每一个位置插入c,可以得到cab,acb,abc,对ba采取同样的操作。最终可以得到全排列的6种结果。代码如下:
# -*- coding:utf-8 -*-
class Solution:
def Permutation(self, ss):
# write code here
ans=[]
SrcStr=[ss[0]]
for i in range(1,len(ss)):
DstStr = [] #用来保存每次插入单个字符后的字符串list
for j in range(len(SrcStr)):
DstStr.extend(self.insertChar(SrcStr[j],ss[i])) #将生成的全排列好的子串保存,下一次全排列使用
SrcStr=DstStr
ans = sorted(list(set(SrcStr))) # 去掉重复的字符串后按字典序排序
return ans
def insertChar(self,string,char): #将一个字符插入一个字符串中
ans=[]
for i in range(len(string)+1):
ans.append(string[:i]+char+string[i:])
return ans
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个结点,然后两链表同时后移,第一个相同的结点即为公共结点。代码如下:
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
len1,len2=0,0
head1=pHead1
head2=pHead2
while pHead1:
pHead1=pHead1.next
len1+=1
while pHead2:
pHead2=pHead2.next
len2+=1
if len1<len2:
head1,head2=head2,head1
diff=abs(len1-len2)
fast,slow=head1,head2
while diff:
fast=fast.next
diff-=1
while fast:
if fast==slow:
return slow
fast=fast.next
slow=slow.next
return None #没有公共节点,返回空
3.找到链表环的入口
剑指offer上的思路:
第一步,判断链表是否存在环。利用快慢指针,快指针每次走两个结点,慢指针每次走一个结点。若存在环,则两指针会在环内相遇。
第二步:确定环中结点的数目。由于相遇时快慢指针均在环中,现在让慢指针不动,快指针每次移动一个结点,直到两指针相遇,记录下快指针走过的结点的数目LoopNumber。
第三步:让p1,p2两个指针均指向头节点,p1先走LoopNumber个结点,然后两结点同时移动,当两结点相遇时即为环的入口处。
代码如下:
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
slow=fast=pHead
while fast.next:
fast=fast.next.next
slow=slow.next
if not fast:
return None
if fast==slow:
break
slow=pHead
while slow and fast and slow!=fast:
slow=slow.next
fast=fast.next
return fast
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
5. rand5()生成rand7()
def rand7():
res=8
while res>7:
res=5*(rand5()-1)+rand5()
return res
改进写法:
def rand7():
res=22
while res>21:
res=5*(rand5()-1)+rand5()
return res%7+1
6.
给定一个无重复元素的数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的数字可以无限制重复被选取。
说明:
- 所有数字(包括
target
)都是正整数。 - 解集不能包含重复的组合。
示例
输入: candidates = [2,3,6,7], target = 7,所求解集为:[[7],[2,2,3]]
class Solution(object):
def combinationSum(self, candidates, target):
self.ans=[]
candidates.sort()
self.dfs(candidates,target,[],0)
return self.ans
def dfs(self,nums,target,sublst,last):
if target==0:
self.ans.append(sublst[:])
if target<nums[0]:
return
for n in nums:
if target<n:
return
if n<last:
continue
sublst.append(n)
self.dfs(nums,target-n,sublst,n)
sublst.pop()
7.KMP
#coding:utf-8
#朴素匹配
def naive_match(s, p):
m = len(s); n = len(p)
for i in range(m-n+1):#起始指针i
if s[i:i+n] == p:
return True
return False
#KMP
def kmp(s, p):
m = len(s); n = len(p)
cur = 0#起始指针cur
table = partial_table(p)
while cur<=m-n:
for i in range(n):
if s[i+cur]!=p[i]:
cur += max(i - table[i-1], 1)#有了部分匹配表,我们不只是单纯的1位1位往右移,可以一次移动多位
break
else:
return True
return False
#部分匹配表
def partial_table(p):
prefix=[] #前缀集合
postfix=[] #后缀集合
res=[0]
for i in range(1,len(p)):
prefix.append(p[:i])
postfix=[p[j:i+1] for j in range(1,i+1)]
intersection=[v for v in prefix if v in postfix] #前缀集合和后缀集合的交集不一定只有一个元素
maxlen=max(map(len,intersection)) if intersection else 0 #保存交集中长度最大的元素的长度
res.append(maxlen)
return res
print naive_match("BBC ABCDAB ABCDABCDABDE", "ABCDABD")
print partial_table("ABCDABD")
print kmp("BBC ABCDAB ABCDABCDABDE", "ABCDABD")