算法笔试题练习

最近又是跳槽和校招高峰期,网上也流传各大公司的算法笔试题,看了一些题,自己做做练习,以下都是python的实现

1.二分法求极值,返回一个tuple(min,max)

def binMax_Min(A,left,right):
    mid=(left+right)/2
    #初始化当前极值
    min1,max1=A[left],A[right]
    min2,max2=min1,max1
    #二分递归返回极值
    if(mid>left):        
        min1,max1=binMax_Min(A,left,mid)
    if((mid+1)<right):
        min2,max2=binMax_Min(A,mid+1,right)
    #将极小值存于min1中
    if(min1>min2):min1=min2
    #将极大值存于max1中
    if(max1<max2):max1=max2
    #比较极小值和极大值,返回结果
    if(min1<max1):
        return min1,max1
    else:
        return max1,min1

 

2.求平方根

#@sqrt精度
EPSION=0.000001
def sqrt(num):
    low=EPSION
    high=EPSION
    mid=0.0
    _sqrt=0.0
    #如果数是小于1的正数
    if(num<1.0):
        high+=1.0
    else:high=num+1.0
    #如果原数据不等(在精度范围内),循环求的
    while (_sqrt-num)>EPSION or (_sqrt-num)<-EPSION:
        mid=(low+high)/2.0
        _sqrt=mid*mid
        if(_sqrt>num):high=mid
        else:low=mid
    return mid

3.给定一个有序数组a,长度为len,和一个数X,判断A数组里面是否存在两个数,他们的和为X,bool judge(int *a, int len, int x),存在返回true,不存在返回false(题目摘自原链接)

求和问题,刚开始只想到了首先遍历数组A,根据A[i]+A[k]=sum然后二分查找k的值,时间复杂度为外层遍历N,加上内层二分查找lgN,复杂度是O(N*lgN).

算法一:

'''
找出数组A中和为sum的2个数(只找出第一队)
'''
def findSumNums(A,sum):
    len_A=len(A)
    for i in range(len_A):
        temp=binarySearch(A,0,len_A-1,sum-A[i])
        if(temp<>-1 and temp<>i):
            return A[i],A[temp]
    return None
'''
二分查找,返回key的索引值,未找到返回-1
'''
def binarySearch(A,left,right,key):
    while(left<=right):
        mid=(left+right)/2
        if(A[mid]>key):
            right=mid-1
        elif(A[mid]<key):
            left=mid+1
        else:return mid
    return -1

后来看了divid的思路,通过求补的方式,时间复杂度可以到达O(N)。

算法二:

def findSumNums2(A,sum):
    len_A=len(A)
    B=[]
    for x in range(len_A):
        B.append(sum-A[x])
    j=len_A-1
    i=0
    print B
    while(i<j):
        print A[i],B[j]
        if(B[i]>A[j]):
            i+=1
        elif(B[i]<A[j]):
            j-=1
        else:
            return A[i],A[j]        
    return None

可以看出,算法二是先申请大小和A一样的数组B,然后将A数组中元素求sum的“补数”赋值给B。最后遍历数组A和B,如果找到A数组A[i]和补集B数组B[j]中元素值相等,就证明数组A[i]+A[j]=sum。

4、给定有n个数的数组a,其中超过一半的数为一个定值,在不进行排序、不开设额外数组的情况下,以最高效的算法找到这个数:int find(int *a, int n)(题目摘自原链接)

这个题以前在编程之美看过,后来又忘记了,现在重写以备记忆。

'''
给定数组中有元素N超过一半,找出他
'''
def findMoreHalf(A):
    count=0#计数器,相异递减,相同递增
    num=None#存放返回的元素
    for i in A:
        if(count==0):
            num=i
            count+=1
        else:
            if(i==num):
                count+=1
            else:
                count-=1
    return num

以上算法关键一步是计数器count的变化,通过取出A[i]于前項相异后count=0,因为在一个数组A中值为n元素(n.number>A.length/2),这必有最後是超过一半的元素。

 

 

 

posted on 2013-09-26 20:08  无为在歧路  阅读(251)  评论(0编辑  收藏  举报

导航