劍指offer(第二版)讀書筆記以及編程題目python版答案(一)
- 題目一:找出數組中重復的數字
- 題目二:不修改數組找出重復數字
- 題目三:二維數組中的查找
- 題目四:替換空格
github地址:https://github.com/ciecus/leetcode_answers/tree/master/jianzhi_offer
題目一:找出數組中重復的數字
書P39
github代碼名稱:t1_duplicated_numbers.py
在一個長度為n的數組里的所有數字都在0~n-1的范圍內。數組中某些數字是重復的,但不知道有幾個數字重復了,也不知道每個數字重復了幾次。請找出數組中任意一個重復的數字。例如,如果輸入長度為7的數組{2,3,1,0,2,5,3},那么對應的輸出是重復的數字2或者3.
解題思路
思路一:先排序,排序的時間復雜度為O(nlogn),然后從頭到尾掃描 思路二:利用哈希表,字典結構,時間復雜度O(n),空間復雜度O(n) 思路三【比較復雜】:數組中的數字都在0~n-1的范圍內。如果這個數字中沒有重復的數字,排序之后數字i將出現在下標為i的位置。 所以可以從頭到尾掃描這個數組的每個數字,當掃描到下標為i的數字時,首先比較這個數字是不是等于i,如果不是就拿它和第m個數字進行比較。如果它和m個數字相等就找到了一個重復數字。如果和第m個數字不想等,就和第m個數字交換?!咎珡碗s了,暫緩】
測試用例
(1)長度為n的數組里包含一個或者多個重復的數字。
(2)數組中不包含重復的數字
(3)無效測試用例(輸入空指針:長度為n的數組中包含0~n-1之外的數字)
==輸入格式 == 數組長度n 輸入數組 長度為n的列表 例如: 3 1 2 2
代碼
方法一:
import sys
def duplicated_number_1(n,values):
if (len(values) != n) |(len(values)==0):
print('the wrong input')
else:
values.sort()
dup_list = []
for i in range(n-1):
if values[i] == values[i+1]:
dup_list.append(values[i])
dup_list = set(dup_list)
if len(dup_list)>0:
string = ''
for dup in dup_list:
string += str(dup)+'\t'
print(string)
else:
print('no duplicates')
if __name__ == "__main__":
n = input()
values = [int(x) for x in sys.stdin.readline().strip().split()]
duplicated_number_1(n, values)
方法二:
def duplicated_number_2(n,values):
if (len(values) != n) | (len(values) == 0):
print('the wrong input')
else:
value_dict = {}
dup_list = set([])
for value in values:
if value in value_dict:
dup_list.appen(value)
dup_list = set(dup_list)
if len(dup_list) > 0:
string = ''
for dup in dup_list:
string += str(dup) + '\t'
print(string)
else:
print('no duplicates')
題目二:不修改數組找出重復數字
書P41
在一個長度為n+1的數組里的所有數字都在1~n的范圍內,所以數組中至少有一個數字時重復的。請找出數組中任意一個重復的數字,但不能修改輸入的數組。例如,如果輸入長度為8的數組{2,3,5,4,3,2,6,7},那么對應的輸出時重復的數字2或者3。
思路分析
和上一題類似,但是不能修改數組,所以就不能直接排序了。 但是使用哈希表的空間復雜度為o(n) 如果優化的話,可以從二分查找的角度出發,調用countrange函數,調用O(logn)次,每次需要O(n)的時間,總時間復雜度為O(nlongn),空間復雜度為O(1)。和哈希表相比的空間換時間。
題目三:二維數組中的查找
書p44
github代碼名稱:t3_find_index.py
在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組匯總是否含有該整數。 例如下面數組
1 | 2 | 8 | 9 |
---|---|---|---|
2 | 4 | 9 | 12 |
4 | 7 | 10 | 13 |
6 | 8 | 11 | 15 |
思路分析
這道題比較巧妙的技巧應該從右上角搜索。
如果搜索數字7:
對于右上角的數字9,9是第四列最小的數字,因為9大于7,所以7不可能在第4列, 同理不在第三列,所以應在在第2列或者第1列,
然后從最右上角的數字2往下搜索。 因為2是第一行現在剩下的最大的數字,所以不在第一行, 然后4是第二行剩下的最大數字,所以不在第二行,
然后就搜索到了7。
假如搜索數字5,從4往下接著搜索,然后發現7大于5,所以5不在第二列。
往左走到4,發現4小于5,所以往下走。 然后是6大于5,往左走,發現不可以了。
就結束,找不到。
思路總結
從右上角開始遍歷,如果待比較的數字小于右上角的數字,就往左走,如果大于右上角的數字就往下走,直到out of index終結。
測試用例
(1)二維數組中包含查找的數字
(2)二維數組中沒有查找的數字
(3)特殊輸入用例,輸入空指針
輸入格式:
待查找的數組num
行數n,
列數m,
數組
輸出格式:如果找到輸出yes 否則輸出none 例如 7 3 2 1 2 2 4 4 6
代碼
import sys
def find_number(num,n,m,matrix):
y = 0
x = m-1
while num != matrix[y][x]:
if num < matrix[y][x]:
if x-1<0:
return "None"
else:
x-=1
if num >matrix[y][x]:
if y+1
題目四:替換空格
書p51
github代碼名稱:jianzhi_offer/t4_replace_space.py
請實現一個函數,把字符串中的每個空格替換成"%20",例如,輸入“we are happy。”則輸出"we%20are%20happy."
思路分析
(1)如果一個空格替換成"%",“2”,"0"這3個字符,因此字符串會變長。所以如果沒有測試用例應該提問面試官是不是覆蓋。
(2)替換操作就是每次往后移動兩個字節,但是復雜度為 O ( n 2 ) O(n^2) O ( n 2 )
(3)可以先遍歷數空格個數,然后進行替換。使用兩個指針,p1和p2,p1指向原字符串的末尾,p2指向替換之后的字符串的末尾,然后直到p1和p2位置相等為止。 圖例:
測試用例
(1)輸入字符串包含空格??崭裎挥谧钋懊?,空格位于最后面,空格位于中間,連續有多個空格
(2)輸入的字符串中沒有空格
(3)特殊用例,輸入為空字符串,輸入只有一個空格
代碼
import sys
def replace_space(string):
p1 = len(string)-1
if p1 <0:
return "None"
else:
i = 0
for char in string:
if char == " ":
i += 1
p2 = p1+2*i
string_new = ['0' for i in range(p2)]
while p2!=p1:
char = string[p1-1]
if char != " ":
string_new[p2-1] = string[p1-1]
p2-=1
p1-=1
else:
string_new[p2-3:p2] = ['%','2','0']
p2-=3
p1-=1
string_new[:p2] = string[:p1]
return string_new
if __name__ == "__main__":
string = list(sys.stdin.readline())
print("".join(replace_space(string)))
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
