zoukankan      html  css  js  c++  java
  • 算法笔试题练习

    最近又是跳槽和校招高峰期,网上也流传各大公司的算法笔试题,看了一些题,自己做做练习,以下都是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),这必有最後是超过一半的元素。

  • 相关阅读:
    学电脑入门与提高
    Autodesk Revit Architecture 2014官方标准教程
    Photoshop移动UI界面设计实用教程 全彩超值版
    中文版SQL Server 2000开发与管理应用实例
    Excel2016数据处理与分析从新手到高手
    云计算(第三版)
    无线局域网搭建与管理
    R语言数据挖掘
    Spring 3.0就这么简单
    SVN使用教程总结
  • 原文地址:https://www.cnblogs.com/keily/p/3341433.html
Copyright © 2011-2022 走看看