1.アルゴリズムベース+再帰アルゴリズム+検索アルゴリズム

1.アルゴリズムの重要性

  1. アルゴリズムエンジニア
  2. コード思考を行使し、コードをより効率的に書く
  3. アプリケーション面接(筆記試験/コンピューター試験)

第二に、アルゴリズム(アルゴリズム)

概念:一种设计过程,解决问题的办法。
Niklaus Wirth:“程序=数据结构+算法”

算法需要有输入和输出

ここに画像の説明を挿入

1.時間の複雑さ

1.1はじめにと問題分析

ここに画像の説明を挿入明らかに、速く走る最初のもの!

类⽐⽣活中的⼀些事件,估计时间:
眨⼀下眼    =》一瞬间
⼝算“29+68”  =》几秒
烧⼀壶⽔ =》几分钟
睡⼀觉 =》 几个小时
完成⼀个项⽬ =》几天/几星期/几个月
⻜船从地球⻜出太阳系 = 几年

時間計算量は、アルゴリズムの効率を評価するために使用される式です。
例としてPythonを取り上げます

print('hello world')

この文の時間計算量は次のように記録されます:O(1)
ここで、1は単位を意味します。文の印刷、加算、減算、乗算、除算、割り当てなどの単純な文によって浪費される時間を単位として使用することに同意します。

for i in range(n):
	print('hello world')

この場合、このコードの時間計算量はO(n)です。これは、「1」をn回実行したためです==》 n * 1 = n

同族の

for i in range(n):
	for j in range(n):
		print('hello world')

時間計算量はO(n²)として記録されます

注:
ここでの単位は正確な概念ではありません。無限に繰り返されるプロセスに比べて、実行が制限された単純なステートメント(printステートメント、加算、減算、乗算、除算、代入)は依然として1つの単位と見なすことができます。

a = 2
print('hello world')
c = 4 + a

このプログラムの時間計算量は、O(3)ではなくO(1)のままです。

同じ

for i in range(n):
	print('Hello World’)
	for j in range(n):
		print('Hello World')

時間計算量は次のとおりです。O(n *(n + 1))の代わりにO(n²)はO(n²+ n)です

ここに画像の説明を挿入
以下の問題については、ハーフ問題と呼びます。

n = 64
while n > 1:
 print(n)
 n = n // 2
#输出
#64 
#32 
#16
#8
#4
#2

時間計算量を計算する方法は?

解:设简单语句执行的次数(单位)为n
则:2**n=64 ==》 n = log2 64 =6
时间复杂度:O(n) = O(log2 64) = O(log 64)

アルゴリズムプロセスが周期的に半分になると、lognが複雑さの式に表示されます。

1.2時間計算量と乾物の要約

》时间复杂度是⽤来估计算法运⾏时间的⼀个式⼦(单位)。 
》⼀般来说,时间复杂度⾼的算法⽐复杂度低的算法慢。 
一般:因为程序运行时间长短还会受限于机器的性能这个物理因素。
》常⻅的时间复杂度(按效率排序) 
	》O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n2logn)<O(n3) 
》复杂问题的时间复杂度 
	》O(n!) O(2n) O(nn)

1.3アルゴリズムの複雑さを簡単かつ迅速に判断する方法(最も単純な状況に適しています)

  • 問題のサイズnを決定します

  • サイクル半減プロセス—》ログ

  • 約n- "nのk乗のk層サイクル

  • 複雑さ:アルゴリズム実行プロセスに基づいて判断する

2.スペースの複雑さ

空间复杂度:用来评估算法内存占用大小的式子
空间复杂度的表达方式和时间复杂度完全一样
	》算法使⽤了⼏个变量:O(1) 
	》算法使⽤了⻓度为n的⼀维列表:O(n) 
	》算法使⽤了m⾏n列的⼆维列表:O(mn)


ほとんどの場合、「時間の空間」とは、時間の値が空間の値よりも大きいことを意味します。

3つの再帰的アルゴリズム

1.再帰的特性

再帰は本質的にループです。理論的には、再帰で実行できることはすべてループで実行できますが、場合によっては、再帰はループよりも実装が簡単です。

	特点:
	1.调用自身
	2.结束条件
def func1(x):
	print(x)
	func(x-1)

これは再帰ではありませんが、終了条件のない無限ループです

def func2(x):
	if x>1:
		print(x)
		func(x-1)

これは
同じ再帰的です

def func3(x):
 if x>0:
 	print(x)
	func2(x+1)

これは再帰ではありません

def func4(x):
 if x>0:
	func4(x-1)
 	print(x)

これは再帰です。
印刷を示すために細いバーを使用し、func2の動作をよりよく示すために関数を示すために大きなボックスを使用します。xが3で、
ここに画像の説明を挿入
3、2、1を順番に出力し、func4(3)が1、2、3を順番に出力するとします。
ここに画像の説明を挿入

1.2再帰的な例:ハノイの塔の問題

神话背景:(其实是一个数学家瞎扯的,骗你来学汉诺塔)
	⼤梵天创造世界的时候做了三根⾦刚⽯柱⼦,在⼀根
柱⼦上从下往上按照⼤⼩顺序摞着64⽚⻩⾦圆盘。
 
	⼤梵天命令婆罗⻔把圆盘从下⾯开始按⼤⼩顺序重新
摆放在另⼀根柱⼦上。 

	在⼩圆盘上不能放⼤圆盘,在三根柱⼦之间⼀次只能
移动⼀个圆盘。 

	64根柱⼦移动完毕之⽇,就是世界毁灭之时。

ここに画像の説明を挿入
プレートの数はnであると仮定します:
"n = 0の場合:何もしない、問題は終わります
" n = 1の場合:A = "C
" n = 2の場合:小さいプレート= "B、大きいプレート=" C 、小さいプレート=》 B
》 n = 3の場合:小さいものから大きいものへのプレートはそれぞれ
1、2、3としてマークされます》次に:1 =》 C、2 =》 B、1 =》 B、3 =》 C、 1 =》 A、2 =》 C、1 =》 C
…………………………
》 n = nの場合:n-1個の小さなプレートと1個の大きなプレートがあることがわかり
ます。1。nを入れます。 -1小さなプレートをCからBに通します
"2.大きなプレートをCに
通します" 3.n-1の小さなプレートをAからCに通し
てタスク完了します。

在这个过程中,我们简化了问题的规模,其实这是递归的核心,我之前学递归的时候,总是把关注点放在大规模和小规模问题之间发生了什么这个点上,想也想不清……现在感觉只需要关注怎么把问题规模缩小的和递归终止条件即可。

コード:

def hanoi(n,a,b,c):
	#这里的n是盘子数,a是盘子一开始在的位置,c是终点位置,b是过度位置
	if n>0: #n=0任务完成
		hanoi(n-1,a,c,b)
		print(f'{a}=>{c}') #模拟最后一个盘子从a到c
		hanoi(n-1,b,a,c)

結果:
a => c
a => b
c => b
a => c
b => a
b => c
a => c
以前の手動シミュレーションプロセスと比較できます。

1.3ハノイの興味深い塔

》汉诺塔移动次数的递推式:h(x)=2h(x-1)+1 

》h(64)=18446744073709551615 

》假设婆罗⻔每秒钟搬⼀个盘⼦,则总共需要5800亿年

4、検索アルゴリズム

検索:一部のデータ要素で、特定の方法を使用して、指定されたキーワードと同じデータ要素を検索するプロセス。
リスト検索、線形テーブル検索とも呼ばれます
:リストから指定された要素を検索します"入力:リスト、検索する要素
" "出力:見つかりました:要素インデックスが見つかりません:なし/ -1
組み込みのリスト検索関数:index() 、その効果は上記のとおりですが、要素が見つからない場合は例外がスローされるという違いがあります

lis = [1,2,3,4,5]
print(lis.index(1))
print(lis.index(6))

結果

0トレースバック(最後の最後の呼び出し):ファイル
「C:/ Users / LENOVO / Desktop /算法.py」、5行目、
print(lis.index(6))ValueError:6はリストにありません

1.順番に検索

順次検索:線形検索とも呼ばれます。リストの最初の要素から開始し、要素が見つかるか、検索がリストの最後に到達するまで順次検索します。
時間計算量:O(n)、nはリストの長さです。ここでは、特に1次元リストを参照します。

> def linear_search(data_set,value):
	for i in range(len(data_set)):
		if data_set[i] == value:
			return i
		

結果:
ここに画像の説明を挿入

2.二分探索/半探索

二分探索:二分探索とも呼ばれます。順序付きリストの最初の候補領域から始めて、検索する値を候補領域の中間値と比較することにより、候補領域を選択するたびに半分に減らすことができます。

例:
ここに画像の説明を挿入バイナリ検索は次のように実行されます。

最初の検索:left = 0、right = 8、ここで、leftとrightは要素
mid = 4の添え字であり、中央のインデックス(中央の値)に対応する値は5、5> 3です
。2番目の検索:前回5> 3で、リストが小さいものから大きいものまである場合、検索する値はmidの左側にあり、この時点ではright = mid-1 = 4-1 = 3、left = 0であることがわかります。変更なし、mid = \(左+右)// 2(添え字は整数値)mid = 1、中央の値は2、2 <3 3
番目の検索:検索する値が右側にあると判断できます2番目の検索結果によるmidの場合、left = mid + 1 = 1 + 1 = 2、right = 3は変更されません、mid =(2 + 3)// 2 = 2、対応する値は3、検索は終了します。

left> rightが中央の領域に値がないことを意味する場合、要素が検索リストに含まれておらず、検索が終了することを意味することに注意してください。

Pythonの実装:

lis = [1,2,3,4]
def bin_search(data_set,value):
    left,right = 0,len(data_set)-1
    while left <= right:
        mid = (left+right)//2
        if data_set[mid]==value:
            return mid
        elif data_set[mid]>value:
            high = mid-1
        else:
            left=mid+1

    return -1
res =bin_search(lis,6)
print(res)

結果:
ここに画像の説明を挿入
時間計算量:O(logn)nは1次元リストの長さです

3.比較する

通常、二分探索は線形探索よりも高速ですが、二分探索の前提はリスト要素を順番に並べることであるため、ソート処理があります。リスト要素が多い場合、ソートに時間がかかります。
したがって、これら2つの検索方法を選択する方法についても、特定の状況を考慮する必要があります。
検索は何度も使用されますが

Pythonの並べ替え+バイナリ検索インデックス()は順次検索ですps:pythonには並べ替えメソッド
1.sort()、
ここに画像の説明を挿入
2.sorted()が付属しています


lis = [1,2,3,4,5]
res = sorted(lis,key=lambda x:-x)
print(res)

結果
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_49821869/article/details/112112338