第一題:遞歸
1.給一個dict或者json 求 value大於53 並且為int 將該value 轉換為str
mydict1 = {"a":{"a":[1,2,3]},
"b":{"b":1}}
def Foo(mydict):
for _,v in mydict.items():
if isinstance(v,dict):
Foo(v)
elif isinstance(v,int) and ord(v) > 53:
v = str(v)
elif isinstance(v,list):
for i in v :
Foo(i)
elif isinstance(v,tuple):
for i in v:
Foo(i)
第二題:邏輯
2. 給一個數組 [7,3,5,6,4] 最大值不能在比他小的值前面,求最大值和最小值的差?
a = [7,3,5,6,4]
big = 0
small = 0
index = 0
for i in a:
if small == 0:
small = i
if i > big:
if index+1 == len(a):
if i > big:
big = i
elif i > a[index+1]:
pass
else:
big = i
if i < small:
small = i
index += 1 #0 1 2
over = big - small
print(over)
按照這種姿勢求:
第三題:python生成器
#!/usr/bin/python # -*- coding:utf-8 -*- i = [1,2,3,4] u = (j for j in i) #通過列表生成式,變成了個生成器 print(u,type(u)) """ <generator object <genexpr> at 0x10457af10> <class 'generator'> """
第四題:單例模式
import threading
import time
class singleclass(object):
_instance_lock = threading.Lock()
def __init__(self):
time.sleep(1) #加入sleep之后就看出來內存地址不一致,這種情況需要考慮加鎖解決
@classmethod
def instance(cls,*args,**kwargs):
if not hasattr(singleclass,"_instance"):
with singleclass._instance_lock:
if not hasattr(singleclass,"_instance"):
singleclass._instance = singleclass(*args,**kwargs)
return singleclass._instance
def task():
obj = singleclass.instance()
print(obj)
for i in range(100):
t = threading.Thread(target=task)
t.start()
基於裝飾器的單例模式:
#!/usr/bin/python
# -*- coding:utf-8 -*-
import threading
def Singleton(cls):
_instance_lock = threading.RLock()
_instance = {}
def _singleton(*args,**kwargs):
if cls not in _instance:
with _instance_lock:
_instance[cls] = cls(*args,**kwargs)
return _instance[cls]
return _singleton
@Singleton
class A(object):
a = 1
def __init__(self, x=0):
self.x = x
a1 = A(2)
a2 = A(3)
print(id(a1))
print(id(a2))
print(a1.x)
print(a2.x)
代碼解析:
代碼分析:第1行,創建外層函數singleton,可以傳入類 第2行,創建一個instances字典用來保存單例 第3行,創建一個內層函數來獲得單例 第4,5,6行, 判斷instances字典中是否含有單例,如果沒有就創建單例並保存到instances字典中,然后返回該單例 第7行, 返回內層函數get_instance #創建一個帶有裝飾器的類 @singleton class Student: def __init__(self, name, age): self.name = name self.age = age 在Python中認為“一切皆對象”,類(元類除外)、函數都可以看作是對象,既然是對象就可以作為參數在函數中傳遞,我們現在來調用Student類來創建實例,看看實現過程。 #創建student實例 student = Student(jiang, 25) @singleton相當於Student = singleton(Student),在創建實例對象時會先將 Student 作為參數傳入到 singleton 函數中,函數在執行過程中不會執行 get_instance 函數(函數只有調用才會執行),直接返回get_instance函數名。 此時可以看作Student = get_instance,創建實例時相當於student = get_instance(jiang, 25),調用get_instance 函數,先判斷實例是否在字典中,如果在直接從字典中獲取並返回,如果不在執行 instances [cls] = Student(jiang, 25),然后返回該實例對象並賦值非student變量,即student = instances[cls]。
第五題 super解析:
class BaseResponse(object):
def __init__(self):
print(123)
class LikeResponse(BaseResponse):
def __init__(self):
self.code = 0
super(LikeResponse,self).__init__()
#執行父類的__init__()方法
if __name__ == '__main__':
g = LikeResponse()
"""
123
"""
第六題 linux shell 腳本中冒號的意思(:)
: 在shell里是什么都不做,但返回值為真
例如
while :; do
command
done
或者
for i in `seq 1 10`; do
:
done
此處相當於python里的pass
第七題: linux shell腳本中
ETCD_NAME=${1:-"default"} #如果$1沒傳遞數據 默認值就是default
ETCD_LISTEN_IP=${2:-"0.0.0.0"}
ETCD_INITIAL_CLUSTER=${3:-}
第八題:python 列表引用類型
def f(x,l=[]):
for i in range(x):
l.append(i*i)
print(l)
f(2)
f(3,[1,2,3])
f(3)
"""
[0, 1]
[1, 2, 3, 0, 1, 4]
[0, 1, 0, 1, 4]
"""
第九題:二分查找非遞歸方法
二分查找:
我們手里有一個長度為n的正序數列,當我們想查找一個數 x是否在這個數列當中的時候
1 取數列正中間的數mid,
如果mid和x相等,則找到結果,查找成功 返回True
如果mid比x大,則x應該在mid的左側,我們把mid左側當作一個新的數列li
如果mid比x小,則x應該在mid的右側,我們把mid右側當作一個新的數列li
2 對於新的數列li 進行1的查找工作
3 一直重復上面查找,生成新的數列li為空的時候則 數列當中沒有數x 返回False
時間復雜度:最優O(1) 我們取第一次中間數mid 找到了 這種概率很低
最壞O(log n) 假設n個數的數列,每次把數列分成兩半,n除以多少次2 等於1 呢? log n次
遞歸實現二分法查找
#遞歸實現二分查找 li是列表 item是要查找的元素
def merge_search( li ,item ):
#傳來的列表每次都是新生成的,如果發現里面沒有元素,則是查找到盡頭都沒找到
if not li :
return False
mid = len(li)//2 #mid記錄li的中間位置
#檢查一下 如果中間這個數就是要找的元素 返回真
if li[mid] == item :
return True
# 如果mid比item大,說明item可能會出現在mid左邊,對左邊再查找
elif li[mid]> item :
return merge_search( li[:mid] ,item )
# mid 比item小,說明item有可能在mid右邊,對右邊再查找
else :
return merge_search( li[mid+1:] , item )
if __name__ == '__main__':
li = [1,2,3,4,5,6,7]
print( merge_search(li , 0) ) #False
print( merge_search(li , 1) ) #True
非遞歸查詢
def merge_search( li , item ):
#獲取li的開始 結束
start = 0
end = len(li)-1
#只要start和end 還沒錯開 就一直找
while start <= end :
#通過計算獲取當前查找范圍的中間位置
mid = (start + end)//2
#如果中間數就是item則返回True
if li[mid] == item :
return True
#如果mid比item大,說明item可能會出現在mid左邊,對左邊再查找
elif li[mid]> item :
end = mid - 1
# mid 比item小,說明item有可能在mid右邊,對右邊再查找
else :
start = mid + 1
#跳出循環說明沒找到 返回錯誤
return False
if __name__ == '__main__':
li = [1,2,3,4,5,6,7,8]
print( merge_search(li , 8) ) #True
print( merge_search(li , 0) ) #False
算法題:
兩個乒乓球隊進行比賽,各出三人。甲隊為a,b,c三人,乙隊為x,y,z三人。已抽簽決定比賽名單。有人向隊員打聽比賽的名單。a說他不和x比,c說他不和x,z比,請編程序找出三隊賽手的名單。
import itertools
for i in itertools.permutations('xyz'):
if i[0] != 'x' and i[2] != 'x' and i[2] != 'z':
print('a vs %s, b vs %s, c vs %s' % (i[0], i[1], i[2]))
求一個字符串最長不重復子串
#!/usr/bin/python
# -*- coding:utf-8 -*-
def max_string(st):
# 設置一個result list + 一個max
# 考察的問題,如果對中間list 進行截取,這個時候要考慮,我截取完的list
# 要將新數據append進去,然后在去求一下,長度和max去比較,只有大於max才可以存到最終的結果里
tmp = []
result = []
max_len = 0
for i in st:
if i in result:
if result.index(i) == len(result) -1:
result = []
result.append(i)
if len(result) > max_len:
max_len = len(result)
tmp = result
else:
result = result[result.index(i)+1:]
result.append(i)
if len(result) > max_len:
max_len = len(result)
tmp = result
else:
result.append(i)
if len(result) > max_len:
max_len = len(result)
tmp = result
print(tmp)
if __name__ == '__main__':
st = "abcadefdhigkg"
max_string(st)
"""
output
['e', 'f', 'd', 'h', 'i', 'g', 'k']
"""
一組數據中只有一個數字出現了一次。其他所有數字都是成對出現的。
思路:可以將所有數字進行異或,因為相同數字異或之后結果為0,任何數與0異或得該數字本身。此題中將所有數字進行異或的結果就是需要找的那個數字。
#include <stdio.h>
#include <windows.h>
int main()
{
int arr[] = { 0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0 };
int num = arr[0];
int i = 0;
for (i = 1; i < sizeof(arr) / sizeof(arr[0]);i++)
{
num ^= arr[i]; //整體異或
}
printf("different number is %d\n", num);
system("pause");
return 0;
}
給定一個二叉樹,在樹的最后一行找到最左面的值
