记录一下最近碰到的几个常见编程题

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

猜你喜欢

转载自blog.csdn.net/baike33/article/details/81135485