第一週週報完整 pdf 版下載地址:
https://t.zsxq.com/rBMVzbM
第二週週報完整 pdf 下載地址:
https://t.zsxq.com/YJiiQz7
本週第三週週報請於星球內下載
上週星球活躍度官方數據如下,連續三週星球活躍度都很不錯,感謝星友們的參與,繼續努力+堅持。
Day 18:二分查找算法
Day 17 作業題
寫出幾種常見覆雜度對應的算法,星友們給出的答案都很準確,在這裏參考星友聶磊的答案:
時間複雜度:
常見操作:哈希查找,數組取值,常數加減乘除
: 二分查找
計算數組中所有元素和,最大,最小
: 歸併排序,堆排序,希爾排序,快速排序
:冒泡,選擇排序
:三元方程暴力求解
:求解所有子集
:全排列問題。比如:給定字母串,每個字母必須使用,且一次組合中只能使用一次,求所有組合方式;另外還要經典的旅行商 TSP 問題
下面這幅圖太直觀了:
其中,複雜度爲:, 是難解的問題,,都是可以接受的解,, 的解是夢寐以求的。
Day 18 :二分查找
二分查找算法,binary search algorithm,也稱折半搜索算法、對數搜索算法
它的使用前提:是一種在有序數組中查找某一特定元素的搜索算法。
請補全下面二分查找算法:
# 返回hkey在數組中的索引位置
def binary_search(arr, left, right, hkey):
"""
arr:有序數組
left:查找區間左側
right:查找區間右側
hkey:帶查找的關鍵碼
備註:left, right 都包括在內,找不到返回 -1
"""
#
#
#
Day 19 合併兩個有序序列
Day 18 作業總結
寫出二分查找算法
已知函數原型:
def binary_search(arr,left,right,hkey):
pass
要求補全上述代碼
注意事項:
(left+right) //2 ,更好寫法:left + (right-left)//2
迭代中,一定注意while判斷中等號問題
二分查找的代碼還是很容易寫出bug
迭代二分查找
代碼參考星友 Leven:
def binary_search(arr,left,right,hkey):
while left <= right:
mid = left + (right-left) // 2
if arr[mid] == hkey:
return mid
elif arr[mid] > hkey: # 嚴格大於
right = mid - 1
else: # 此處嚴格小於
left = mid + 1
return -1 # 表示找不到
if __name__ == "__main__":
sorted_list = [1,2,3,4,5,6,7,8]
result = binary_search(sorted_list,0,7,4)
print(result)
遞歸二分查找
def binary_search(arr,left,right,hkey):
if len(arr) == 0:
return -1
if left > right:
return -1
mid = left + (right-left) // 2
if arr[mid] == hkey:
return mid
elif arr[mid] < hkey: # 嚴格小於
return binary_search(arr,mid+1,right,hkey) # 折半
else:
return binary_search(arr,left,mid-1,hkey)
if __name__ == "__main__":
sorted_list = [1,2,3,4,5,6,7,8]
result = binary_search(sorted_list,0,7,4)
print(result)
更多演示動畫
能找到關鍵碼:
不能找到關鍵碼:
Day 19 作業題
合併兩個有序數組 left 和 right:
def merge(left,right):
#補全代碼
#
return temp
思路可參考示意圖:
Day 20 歸併排序算法
Day 19 合併兩個有序數組作業總結
合併兩個有序數組
利用兩個數組原本已經有序的特點:
def merge(left, right):
i = 0
j = 0
temp = []
while i <= len(left) - 1 and j <= len(right) - 1:
if left[i] <= right[j]:
temp.append(left[i])
i += 1
else:
temp.append(right[j])
j += 1
temp += left[i:] + right[j:]
return temp
print(merge([1,3,4],[2,3,3]))
思路可參考示意圖:
Day20 寫出歸併排序算法
歸併排序(MERGE-SORT)是利用歸併的思想實現的排序方法,該算法採用經典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然後遞歸求解,而治(conquer)的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。
歸併排序算法的核心正是 Day 19 的合併兩個有序數組,補全如下代碼:
def merge_sort(lst):
#
#
#
return lst_sorted
歸併排序兩階段:
先分,直到長度1,然後再合:
歸併排序的詳細講解,可參考:https://www.programiz.com/dsa/merge-sort
Day 21 21 天刷題總結
很多星友都一直堅持到現在,21 天整,都說 21 天養成一個習慣,據此推斷,相信你們養成了刷題的習慣~~
下面我們先總結下 Day 20 的歸併排序作業題
Day 20 寫出歸併排序算法
歸併排序(MERGE-SORT)是利用歸併的思想實現的排序方法,該算法採用經典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然後遞歸求解,而治(conquer)的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。
# Python program for implementation of MergeSort
def mergeSort(arr):
if len(arr) >1:
mid = len(arr)//2 # Finding the mid of the array
L = arr[:mid] # Dividing the array elements
R = arr[mid:] # into 2 halves
mergeSort(L) # Sorting the first half
mergeSort(R) # Sorting the second half
i = j = k = 0
# Copy data to temp arrays L[] and R[]
while i < len(L) and j < len(R):
if L[i] < R[j]:
arr[k] = L[i]
i+= 1
else:
arr[k] = R[j]
j+= 1
k+= 1
# Checking if any element was left
while i < len(L):
arr[k] = L[i]
i+= 1
k+= 1
while j < len(R):
arr[k] = R[j]
j+= 1
k+= 1
驗證調用:
# Code to print the list
def printList(arr):
for i in range(len(arr)):
print(arr[i], end =" ")
print()
# driver code to test the above code
if __name__ == '__main__':
arr = [12, 11, 13, 5, 6, 7]
print ("Given array is", end ="\n")
printList(arr)
mergeSort(arr)
print("Sorted array is: ", end ="\n")
printList(arr)
思路可參考示意圖:
歸併排序的詳細講解,可參考:
https://www.programiz.com/dsa/merge-sort
Day 21 打卡
與這麼多星友一起刷題的這21天,請寫出你的心得體會,另外若你有什麼建議,歡迎也反饋一下。
Day 22 21 天刷題總結
很多星友都一直堅持到現在,21 天整,都說 21 天養成一個習慣,據此推斷,相信你們養成了刷題的習慣~~
下面我們看看星友們的刷題心得總結:
Day 21 天刷題總結
節選幾位星友21天刷題總結
還有更多星友的21天打卡總結,在此不一一列舉。
總之,看到大家有收穫,所以與大家一起堅持下去,大的指導方向不變。按照有些星友的反饋,會增加進階題目,同時週末會增加算法學習經驗分享等。
Day 22 打卡:使用遞歸以相反的順序打印字符串
前面的歸併排序,用到遞歸。
遞歸是計算機科學中的一個重要概念。它是計算機算法的基礎。接下來幾天,我們詳細的探討遞歸的原理,如何更高效的使用遞歸解決實際問題。
今天先從一個基礎題目體會遞歸的原理:使用遞歸以相反的順序打印字符串。
def reverse_print(s):
#
#補充完整
#
謝謝大家!
Day 23:
Day 22:使用遞歸以相反的順序打印字符串
先看題目的求解方法。
遞歸方法一:
def reverse_print(s):
if len(s) <= 1:
return s
return reverse_print(s[1:]) + s[0]
使用遞歸,往往代碼會很簡潔,但若不熟悉遞歸,理解起來就會相對困難。
下面藉助示意圖解釋以上遞歸過程:
假如這樣調用 reverse_print
:
reverse_print('abcdef')
那麼遞歸過程時,函數reverse_print
會不斷入棧,示意圖如下:
此時棧頂爲入參 f
的函數,位於示意圖的最底部。
因爲它滿足了遞歸返回條件len(s) <= 1
,所以棧頂函數首先出棧,並返回值 f
,下一個即將出棧的爲入參ef
的函數,其返回值爲fe
,如下所示:
依次出棧:
最後一個留在棧的reverse_print
,即將返回我們想要的結果:
它也出棧後,我們變得到結果 fedcba
以上就是使用遞歸反轉打印字符的方法。
其他使用遞歸反轉字符串的方法,大家多看看其他星友的解法即可。
Day 23:使用遞歸:兩兩交換鏈表中的節點
給定鏈表,交換每兩個相鄰節點並返回其頭節點。
例如,對於列表 1-> 2 -> 3 -> 4,我們應當返回新列表 2 -> 1 -> 4 -> 3 的頭節點。
請補充下面函數:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def swapPairs(self, head: ListNode):
pass # 請補充
Day 24:遞歸生成楊輝三角
先來總結昨天的作業
Day 23:遞歸兩兩交換鏈表中的節點
給定鏈表,交換每兩個相鄰節點並返回其頭節點。
例如,對於列表 1-> 2 -> 3 -> 4,我們應當返回新列表 2 -> 1 -> 4 -> 3 的頭節點。
請補充下面函數:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def swapPairs(self, head: ListNode):
pass # 請補充
使用遞歸的解題思路,見下面示意圖:
兌現爲代碼如下:
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if head is None or head.next is None:
return head
tmp = head.next
r = self.swapPairs(tmp.next)
tmp.next = head
head.next = r
return tmp
連上完整的驗證代碼:
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if head is None or head.next is None:
return head
tmp = head.next
r = self.swapPairs(tmp.next)
tmp.next = head
head.next = r
return tmp
if __name__ == "__main__":
# create ListNode from list a
a = [1, 2, 3, 4, 5]
head = ListNode(a[0])
tmp = head
for i in range(1, len(a)):
node = ListNode(a[i])
tmp.next = node
tmp = tmp.next
# swap pairs
snode = Solution().swapPairs(head)
# check result
tmp = snode
while tmp:
print(tmp.val)
tmp = tmp.next
遞歸使用的訣竅:
每當遞歸函數調用自身時,它都會將給定的問題拆解爲子問題。遞歸調用繼續進行,直到到子問題無需進一步遞歸就可以解決的地步。
剛剛接觸遞歸,使用起來會比較彆扭,大家不妨結合昨天的遞歸調用棧,再多練習幾道遞歸題目,相信會越來越熟練。
Day 24:遞歸生成楊輝三角
給定一個非負整數 numRows,生成楊輝三角的前 numRows 行。
請補全下面代碼:
class Solution:
def generate(self, numRows: int) -> List[List[int]]:
pass
如果你想從零學習算法,不妨加入下面星球,現在是最划算的時候,還提供專門的星友微信交流社羣,每天在星球裏記錄自己的學習過程,學習其他星友的解題分析思路。打卡 300 天退換除平臺收取的其他所有費用。