Python コーディング面接の前に解くべき 10 個のアルゴリズム

Python コーディング面接の前に解くべき 10 個のアルゴリズム

アルゴリズムの練習がなぜ重要なのか?

私が最初に問題を解き始めたときのように世間知らずにならないでください。時々アルゴリズムをいくつか解くのは楽しいと思っていましたが、練習にあまり時間をかけず、ただ問題を解くことだけに専念していました。時々、問題を不注意に解いてしまうこともありますが、なぜそうしたのか理解できません。私自身としては、結局のところ、一日中アルゴリズムを解くというのはちょっとオタクっぽくて、実際の日常の仕事環境では実用的ではなく、長期的に見てもあまり利益をもたらさないだろうと考えていました。

「アルゴリズムを解く方法を知っていると、就職活動で競争上の優位性が得られます」

しかし、プログラマーの場合、日々の業務で複雑な問題が発生するのが現実であり、大企業は求職者の問題解決能力や細部への注意力を収集するための標準化されたプロセスを見つけなければなりません。つまり、あまり知られていない企業でも同様の評価方法を使用する傾向があるため、アルゴリズムを解く方法を知っていると、就職活動中に競争上の優位性が得られることになります。

アルゴリズムをより一貫して解き始めてすぐに、練習したり、これらの問題を解決するための最も効果的な戦略を学んだり、面接に向けて精神的に準備したりするためのリソースがたくさんあることに気付きました。 (Niuke.com、Likou、Lingkouなど)

これらのサイトでは、面接の質問を練習するだけでなく、アルゴリズムを企業別にグループ化したり、人々が面接体験の詳細な概要を共有するアクティブなブログを埋め込んだり、プレミアムプランの一部として模擬面接の質問を提供したりすることさえあります。

最初は問題に本当に苦労してもがっかりしないでください。これは完全に正常なことです。非常に経験豊富な Python プログラマーであっても、十分なトレーニングを受けなければ、多くのアルゴリズムを短期間で解決するのは難しいことに気付くでしょう。

また、面接が期待通りに進まず、アルゴリズムを解き始めたばかりの場合でも、がっかりしないでください。面接に臨む前に、いくつかの質問を準備し、毎日定期的に練習するなど、何ヶ月もかけて準備する人もいます。

トレーニング プロセスを支援するために、電話コーディング面接で何度も出てくる 10 個のアルゴリズム (主に文字列操作と配列を中心としたもの) を以下に選びました。これらの質問のレベルは比較的簡単ですが、簡単に手に入るものが多いので、良い出発点としてご利用ください。

文字列操作

数字を逆にする

  1. # 整数を与えられたら、その逆数を返す
  2. # 数値は負数または整数になります
  3.  
  4. 定義ソリューション(x):
  5. 文字列 = str(x)
  6.      
  7. 文字列[0] == '-'の場合:
  8. 戻る 整数( '-' + 文字列[:0:-1])
  9. それ以外
  10. 戻る 整数(文字列[::-1])
  11.      
  12. print(解(-289))
  13. 印刷(ソリューション(123))
  14.  
  15. 出力:
  16. -132
  17. 543

平均単語長

  1. # 指定された文の平均単語長を返します。
  2. # 最初に句読点を削除することを忘れないでください。
  3.  
  4. sentence1 = 「皆さんこんにちは。私の名前はトムです。オーストラリア出身です。」  
  5. sentence2 = 「Python のアルゴリズムについてもっと学ぶには、一生懸命努力する必要があります!」  
  6.  
  7. 定義ソリューション(文):
  8. ピン  「!?',;." :
  9. 文 =文.replace (p, '' )
  10. 単語 = 文.split()
  11. round(合計(単語数 len(単語) /単語len(単語),2)を返す)
  12.      
  13. print(ソリューション(文1))
  14. print(ソリューション(文2))
  15.  
  16. 出力:
  17. 4.2
  18. 4.08

文字列に対して簡単な計算を適用するアルゴリズムは非常に一般的なので、.replace() や .split() などのメソッドに精通しておくことが重要です。この場合、これらのメソッドは不要な文字を削除し、長さを簡単に測定して合計できる単語のリストを作成するのに役立ちました。

文字列の追加

  1. # 文字列として表される 2 つの非負整数 num1 と num2 が与えられた場合、num1 と num2 の合計を返します。
  2. # 組み込みの BigInteger ライブラリを使用したり、入力を直接整数に変換したりしないでください。
  3.  
  4.  
  5.  
  6. 数値1 = '364'  
  7. 数値2 = '1836'  
  8.  
  9. # アプローチ1:
  10. 定義ソリューション(num1,num2):
  11. 評価(数値1) + 評価(数値2)
  12. str(eval(num1) + eval(num2))を返す
  13.              
  14. print(ソリューション(num1,num2))
  15.  
  16. #アプローチ2
  17. # 長さ1の文字列が与えられた場合、パラメータがUnicodeオブジェクトであれば、ord()関数は文字の表現を返します。
  18. # 文字列の Unicode コード ポイントを表す整数、または引数が 8 ビット文字列の場合はバイト値。
  19.  
  20. 定義ソリューション(num1, num2):
  21. n1, n2 = 0, 0
  22. m1、m2 = 10**(len(num1)-1)、10**(len(num2)-1)
  23.  
  24. iが num1場合:
  25. n1 += (ord(i) - ord( "0" )) * m1
  26. m1 = m1//10
  27.  
  28. i がnum2にある場合:
  29. n2 += (ord(i) - ord( "0" )) * m2
  30. m2 = m2//10
  31.  
  32. str(n1 + n2)を返す
  33. プリント(ソリューション(num1, num2))
  34.  
  35. 出力:
  36. 2200
  37. 2200

どちらのアプローチも同じように優れていると思います。1 つ目は簡潔で、直感的な eval() メソッドを使用して文字列ベースの入力を動的に評価します。2 つ目は ord() 関数を巧みに使用して、文字の Unicode コード ポイントを介して両方の文字列を実際の数値として再構築します。本当に 2 つのうちどちらかを選択しなければならない場合、おそらく 2 番目のアプローチを選択します。これは、最初は複雑に思えるかもしれませんが、より高度な文字列操作アルゴリズムを必要とする問題を解決するときに便利なことが多いためです。

最初のユニークな文字を見つける

  1. #文字列が指定されると、その中の最初の繰り返しのない文字を見つけて、そのインデックスを返します。
  2. #存在しない場合は-1を返します。 # 注意: 入力文字列はすべて小文字です。
  3. #アプローチ1
  4. 定義ソリューション:
  5. 頻度 = {}
  6. iが s場合:
  7. もし私 頻度:
  8. 頻度[i] = 1
  9. それ以外
  10. 頻度[i] += 1
  11. iが範囲(len(s))内にある場合:
  12. 頻度[s[i]] == 1の場合:
  13. 戻る
  14. -1を返す
  15.  
  16. print(solution( 'アルファベット' ))
  17. print(solution( 'バルバドス' ))
  18. print(solution( 'crunchy' ))
  19.  
  20. 印刷( '---' )
  21.  
  22. #アプローチ2
  23. コレクションをインポートする
  24.  
  25. 定義ソリューション:
  26. # ハッシュマップを構築:文字 そしてそれがどのくらいの頻度で現れるか
  27. count = collections.Counter(s) # < -- 単語の出現回数を格納した辞書を返します 
  28. #カウンター({ 'l' :1、 'e' :3、 't' :1、 'c' :1、 'o' :1、 'd' :1})
  29. #インデックスを見つける 
  30. idx、chの列挙場合:
  31. count [ch] == 1の場合:
  32. idxを返す
  33. -1を返す
  34.  
  35. print(solution( 'アルファベット' ))
  36. print(solution( 'バルバドス' ))
  37. print(solution( 'crunchy' ))
  38.  
  39. 出力:
  40. 1
  41. 2
  42. 1
  43. ---  
  44. 1
  45. 2
  46. 1

この場合も、2 つの解決策が提供されています。アルゴリズムにまだ慣れていない場合は、空の辞書から始まる単純なカウンターであるため、最初のアプローチの方が馴染みがあると思われます。

ただし、2 番目のアプローチを理解しておくと、長期的にはより役立ちます。これは、このアルゴリズムでは、文字カウンタを自分で構築するのではなく、単に collection.Counter を使用し、range(len(s)) を enumerate に置き換えたためです。これにより、インデックスの威力をよりエレガントに識別できるようになります。

有効な回文

  1. # 空でない文字列 s を指定すると、最大 1 文字を削除できます。回文にできるかどうかを判定します。
  2. # 文字列には小文字の a ~ z のみが含まれます。
  3. s = 'サドカス'  
  4. 定義ソリューション:
  5. iが範囲(len(s))内にある場合:
  6. t = s[:i] + s[i+1:]
  7. t == t[::-1]の場合:戻り値 真実 
  8.  
  9. s == s[::-1]を返す
  10.    
  11. 解決策
  12.  
  13. 出力:
  14. 真実 

「有効な回文」の問題はまさに古典的であり、さまざまな状況で何度も遭遇する可能性があります。この場合のタスクは、その反対の文字に一致する文字を最大 1 つ削除して天気をチェックすることです。 s = 'sadkas' の場合、関数は 'k' を除外して True を返し、回文である単語 'sadas' を取得します。

配列

モノトーン配列

  1. # 整数の配列が与えられた場合、その配列が単調かどうかを判断します。
  2. A = [6, 5, 4, 4]
  3. B = [1,1,1,3,3,4,3,2,4,2]
  4. 1,1,2,3,7 の
  5.  
  6. 定義ソリューション(数値):
  7. 戻り値(すべて(nums[i] <= nums[i + 1]、 irange(len(nums) - 1)内にある)または  
  8. すべて(nums[i] >= nums[i + 1]、 i範囲 (len(nums) - 1)))
  9.    
  10. 印刷(ソリューション(A))
  11. print(ソリューション(B))
  12. print(ソリューション(C))
  13.  
  14. 出力:
  15. 真実 
  16. 間違い 
  17. 真実 

これはもう一つの非常に一般的な問題ですが、上記の解決策は 1 行で記述できるため、非常にエレガントです。配列が単調となるのは、単調増加または単調減少のいずれかであり、評価配列である場合のみです。上記のアルゴリズムは、反復可能オブジェクト内のすべての項目が True の場合は True を返し、それ以外の場合は False を返す all() 関数の機能を活用します。 all() 関数は、反復可能オブジェクトが空の場合にも True を返します。

ゼロを移動

  1. # 配列numが与えられたら、ゼロをすべて配列の末尾に移動する関数を記述してください。
  2. # ゼロ以外の要素の相対的な順序。
  3. 配列1 = [0,1,0,3,12]
  4. 配列2 = [1,7,0,0,8,0,10,12,0,4]
  5.  
  6. 定義ソリューション(数値):
  7. 数値i場合:
  8. 数値0 の場合:
  9. 数値を削除(0)
  10. 数値を追加(0)
  11. 数値を返す
  12.  
  13. 解(配列1)
  14. 解(配列2)
  15.  
  16. 出力:
  17. [1, 3, 12, 0, 0]
  18. [1、7、8、10、12、4、0、0、0、0]

.remove() メソッドと .append() メソッドは、配列を操作するときに役立ちます。この問題では、まず元の配列に属していたすべてのゼロを削除し、次にそれを同じ配列の末尾に追加するためにこれらを使用します。

空欄を埋めてください

  1. # None値を含む配列が与えられた場合、配列内の最新のNone以外の値でNone値を埋めます
  2. 配列1 = [1,なし,2,3,なし,なし,5,なし]
  3.  
  4. defソリューション(配列):
  5. 有効 = 0
  6. 解像度 = []
  7. 数値i場合:
  8. もし私 なしではない:
  9. res.append(i)
  10. 有効 = i
  11. それ以外
  12. res.append(有効)
  13. 戻り
  14.  
  15. 解(配列1)  
  16.  
  17. 出力:
  18. [1、1、2、3、3、3、5、5]

どちらの場合も、ソリューションにはエッジ ケースを含める必要があります (ここでは簡潔にするために省略しています)。表面的には、これは簡単に構築できるアルゴリズムですが、for ループと if ステートメントで何を達成しようとしているのかを念頭に置き、None 値の操作に慣れる必要があります。

一致する単語と一致しない単語

  1. # 2つの文が与えられた場合、1つの文に現れる単語の配列を返す。
  2. # 別の単語。共通の単語を持つ単語の配列を返します。
  3. sentence1 = '私たちの街であなたに会えて本当に嬉しいです'  
  4. sentence2 = 「この街はひどい嵐に見舞われた」  
  5.  
  6. 定義ソリューション(文1、文2):
  7. set1 = set (sentence1.split())
  8. set2 = set (sentence2.split())
  9.      
  10. sorted(list(set1^set2))、sorted(list(set1&set2))を返します
  11.  
  12. print(解決策(文1、文2))
  13.  
  14. 出力:
  15. [ 私たち 「ある」 によって 重い」、「ヒット」、「で」 会う 私たちの」
  16. 「喜んだ」 「嵐」 「に」 「だった」 「あなた」 ]、
  17. [ '都市' '本当に' ])

この問題は非常に直感的ですが、アルゴリズムでは、set()、intersection() または &、symmetric_difference() または ^ などの非常に一般的な集合演算が利用されており、ソリューションをよりエレガントにするのに非常に役立ちます。

素数配列

  1. # n 未満の k 個の数が与えられた場合、それらの中の素数の集合を返します
  2. # 注: タスクは、間隔内のすべての素数を出力するプログラムを作成することです。
  3. # 定義: 素数とは、1 とそれ自身以外に約数を持たない、1 より大きい自然数です。
  4.  
  5. 35人
  6. 定義ソリューション(n):
  7. 素数 = []
  8. 範囲(n)内のnumの場合:
  9. if num > 1: #すべての素数は 1 より大きい
  10. iが範囲(2, num)内にある場合:
  11. if (num % i) == 0: # 剰余が 0 の場合、その数値は前の数値割ることができることを意味します
  12. 壊す
  13. それ以外
  14. prime_nums.append(数値)
  15. prime_numsを返す
  16. 解決策
  17.  
  18. 出力:
  19. [2、3、5、7、11、13、17、19、23、29、31]

もう一つの古典的な質問でこの記事を締めくくりたいと思います。素数の定義と剰余演算の両方に精通している場合は、谷(n)の範囲を調べることで簡単に解を見つけることができます(剰余演算)。

結論は

この記事では、面接でよく聞かれる 10 個の Python アルゴリズムの解決策を紹介します。有名なテクノロジー企業との面接の準備をしている場合、この記事は一般的なアルゴリズムのパターンに慣れ、より複雑な問題に進むための素晴らしい出発点となります。また、この記事で紹介されている演習 (およびその解答) は、フォース ボタンとカラー ボタンで見つかった問題の部分的な再解釈であることにも注意してください。私はこの分野の専門家からは程遠いので、私が提案する解決策はあくまでも参考的なものにすぎません。

<<:  TensorFlow 2 入門ガイド。初心者必見です!

>>:  面接の質問に必ず読むべき一冊! Python のトップ 5 ソート アルゴリズムとその実装コード

ブログ    
ブログ    

推薦する

...

黄氏の最新インタビュー:チップ不足はなかなか解消されず、次のトランスフォーマーはすでに登場している

Nvidia の GPU が世界を席巻しています。テクノロジー企業は、Nvidia のスーパーコンピ...

...

...

ヘルスケアにおける AI: 注目すべき 3 つのトレンド

COVID-19 パンデミック、メンタルヘルス危機、医療費の高騰、人口の高齢化により、業界のリーダ...

Sinovationは、あらゆるもののインテリジェントな接続を促進するエッジインテリジェンスプラットフォームTurboXを立ち上げました。

[51CTO.comより引用] 2019年を振り返ると、今年は人工知能、モノのインターネット、クラ...

ゲーム開発における機械学習の活用

機械学習のメリット機械学習は多くの分野で驚異的な進歩を遂げてきました。応用分野の観点から見ると、機械...

シリコンバレーの大企業も「名門校の学位」を重視するのでしょうか? Redditの男の魂を問う質問が白熱した議論を巻き起こす

シリコンバレーの大企業からのオファーは多くのプログラマーにとって依然として非常に魅力的であり、今年は...

...

Facebookの広告システムの背後にあるペーシングアルゴリズム

[[163141]]先月、Facebook は 2015 年第 4 四半期の驚異的な財務結果を発表し...

AI研究 | 陸宇:人工知能はオンライン教育を改善する大きな可能性を秘めている

工業情報化部科学技術庁は、感染予防・抑制に努め、感染拡大を阻止するために、「人工知能の力を十分に発揮...

IEEE: AI の時代において、基本的なサイバー衛生で十分でしょうか?

長年にわたり、強力なパスワード、定期的なデータ バックアップ、多要素認証は、個人情報を安全に保つため...

漫画は爆発的な効果でAIに変身し、サーバーが何度も圧倒された

[[436077]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...

...

推論効率は ControlNet の 20 倍以上です。 Google、モバイルデバイスで利用可能な画像生成制御モデル「MediaPipe Diffusion」プラグインをリリース

近年、拡散モデルはテキストから画像への生成において大きな成功を収め、画像生成品質の向上、推論パフォー...