常见python算法小题和一些常考知识点
1、如何不使用^实现异或
异或^与或| 相差在当x和y都为1的时候,或为1 异或为0 因此可以与&上x和y取反的或 即可完成异或的操作。
def xor(x,y):
return (x|y)&(~x|~y)
2、求一个正整数的平方根,要求精度(此处采用梯度下降法和二分查找法来解决)
def grident_descent(y):
x=1
alpha=0.001
deta=1
count=0
while abs(deta)>0.0001:
deta=4*x*(x**2-y)
x-=alpha*deta
count+=1
return x,count
print(grident_descent(2))
#二分查找:求解一个正整数的平方根
def search(y):
start=0
end=y
precision = 0.00001#控制精度
while (end-start >= precision):
mid = (start + end) / 2.0
if mid**2==y:
return mid
elif mid ** 2 > y:
end = mid
else:
start = mid
return start
print(search(3))
3、判断一个数是否是2的n次方
def ispow(n):
m=n&(n-1)
return m==0
4、不使用除操作符实现两个数的除法(减法实现,转换成乘法进行计算)
减法实现
def divide(m,n):
res=0
while m>=n:
m=m-n
res+=1
remain=m
return remain,res#其中res为商,而remain为余数
5、在二维数组中寻找最短路径(可以采用动态规划和递归法,这里采用递归法)
def getMinPath(arr,i,j):
if i==0 and j==0:
return arr[i][j]
if i>0 and j>0:
return min(getMinPath(arr,i-1,j), getMinPath(arr,i,j-1))+arr[i][j]
if i>0 and j==0:
return arr[i][j]+getMinPath(arr,i-1,j)
else:
return arr[i][j]+getMinPath(arr,i,j-1)
def getMinPath2(arr):
if arr==None and len(arr)==0:
return 0
return getMinPath(arr,len(arr)-1,len(arr[0])-1)
6、最长连续重复子串长度(curMaxLen统计的是当前字符的最大重复次数,maxLen统计的是字符重复次数的最大值,当遇见新的字符的时候,此时其连续重复次数curMaxLen应置为1)
def getMaxDupChar(s,stratIndex,curMaxLen,maxLen):
if startIndex==len(s)-1:
retuan max(curMaxLen,maxLen)
if list(s)[startIndex]==list(s)[startIndex+1]:
return getMaxDupChars(s,startIndex+1,curMaxLen+1,maxLen)
else:
return getMaxDupChars(s,startIndex+1,1,max(curMaxLen,maxLen))
7、二维有序数组(行列均递增)高效查找数组中元素(采用二分法,从数组的右上角遍历到左下角,当a[i][j]<data的时候,行+1,当a[i][j]>data的时候,列-1)
def findtarget(array,data):
i=0
rows=len(array)
columns=len(array[0])
j=columns-1
while i<rows and j>0:
if array[i][j]==data:
return True
elif array[i][j]<data:
i+=1
else:
j-=1
return False
8、计算两个数的最大公约数(移位运算的方法求解最大公约数,并使用了更相减损术,两个数(a>b)的最大公约数等于(a-b)和b的最大公约数,同时此处还可以用辗转相除法来做,辗转相除法:两个数的最大公约数(a>b)等于两个数的余数(a%b)和b(小的那个数)的最大公约数)
求两个数的最大公约数,需要注意的是首先判断数是否是偶数与奇数的条件,偶数采用与操作之后结果等于0,奇数采用与操作之后为1,‘
同时除以2运算法为两个大于号方向向右,方向向左则为乘以2
def get_greatest_common_divisor(a,b):
if a==b:
return a
if (a&1)==0 and (b&1)==0:
return get_greatest_common_divisor(a>>1,b>>1)<<1
elif (a&1)==0 and (b&1)!=0:
return get_greatest_common_divisor(a>>1,b)
elif (a&1)!=0 and (b&1)==0:
return get_greatest_common_divisor(a,b>>1)
else:
big=max(a,b)
small=min(a,b)
return get_greatest_common_divisor(big-small,small)
print()函数默认输出带换行结果,可以用end参数控制输出不带换行结果。
9、深拷贝和浅拷贝的区别和理解。
首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别。
深拷贝会重新开辟新的内存空间保存拷贝的对象,浅拷贝对于可变元素如列表来说仍然指向相同的地址,一个改变另一个也有影响,但是对于不可变对象不影响。
10、python的装饰器和闭包函数
其作用和特点是:在不需要对对象做任何代码上的变动下,为已经存在的对象添加额外的功能。
闭包函数是内嵌函数调用了其作用域之外的对象此时的函数就是闭包函数。闭包函数用在装饰器中,实现被装饰函数的新增功能。
python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象(函数的指针)。
11、args,kwargs作为参数传入函数起到什么作用?
args表示的参数以列表的形式传入;kwargs表示的参数以字典的形式传入;
13、python中的生成器和迭代器的区别和理解。
生成器中保存是不断找到下一个元素的算法,节省了空间。
使用迭代器不要求事先准备好整个迭代过程中的所有元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后元素可以不存在或者被销毁。因此迭代器适合遍历一些数量巨大甚至无限的序列。