プログラミング面接で学ぶべきアルゴリズム概念トップ10のまとめ

プログラミング面接で学ぶべきアルゴリズム概念トップ10のまとめ

コーディング面接でよく聞かれるアルゴリズム関連の概念トップ 10 を紹介します。簡単な例を使ってこれらの概念を説明します。これらの概念を完全に理解するにはより多くの努力が必要なので、このリストはあくまでも入門として意図されています。この記事では、Java の観点から問題を検討し、次の概念について説明します。

1. 文字列

2. リンクリスト

3. 木

4. グラフ

5. ソート

6. 再帰と反復

7. 動的プログラミング

8. ビット操作

9. 確率の問題

10. 順列と組み合わせ

1. 文字列

IDE にコード自動補完機能がない場合は、次の方法を覚えておいてください。

  1. toCharyArray() // 文字列に対応する文字配列を取得する 
  2. Arrays.sort() // 配列のソート 
  3. Arrays.toString( char [] a) // 配列を文字列に変換 
  4. charAt( int x) // 特定のインデックスの文字を取得します 
  5. length() // 文字列の長さ 
  6. 長さ// 配列のサイズ 

2. リンクリスト

Java では、リンク リストの実装は非常に簡単です。各ノード Node には値 val と、次のノードを指すリンク next があります。

  1. クラスノード{
  2. 整数値;
  3. 次のノード;
  4.   
  5. ノード( int x) {
  6. val = x;
  7. 次 = null ;
  8. }
  9. }

リンク リストの 2 つの有名なアプリケーションは、スタックとキューです。

スタック:

  1. クラスStack{
  2. ノードトップ;
  3.   
  4. パブリックノードピーク(){
  5. (トップ!= null {
  6. 先頭に戻る;
  7. }
  8.   
  9. 戻る ヌル;
  10. }
  11.   
  12. パブリックノードポップ(){
  13. (トップ == null の場合{
  14. 戻る ヌル;
  15. }それ以外{
  16. ノード temp = new Node(top.val);
  17. 上 = top.next;
  18. 温度を返します
  19. }
  20. }
  21.   
  22. 公共  void push(ノードn){
  23. (n != null )の場合{
  24. n.next = トップ;
  25. 上 = n;
  26. }
  27. }
  28. }

列:

  1. クラスQueue{
  2. ノードが最初、最後。
  3.   
  4. 公共  void enqueue(ノードn){
  5. if (first == null ){
  6. 最初 = n;
  7. 最後 = 最初;
  8. }それ以外{
  9. 最後.次 = n;
  10. 最後 = n;
  11. }
  12. }
  13.   
  14. パブリックノードデキュー(){
  15. if (first == null ){
  16. 戻る ヌル;
  17. }それ以外{
  18. ノード temp = new Node(first.val);
  19. 最初 = first.next;
  20. 温度を返します
  21. }
  22. }
  23. }

3. 木

ここでのツリーは通常、バイナリ ツリーを指し、各ノードには次のように左の子ノードと右の子ノードが含まれます。

  1. クラスTreeNode{
  2. int値;
  3. TreeNode 左;
  4. TreeNode 右;
  5. }

木に関連するいくつかの概念を次に示します。

  1. バランス型と非バランス型: バランス型の二分木では、各ノードの左サブツリーと右サブツリーの深さは最大 1 (1 または 0) 異なります。
  2. 完全二分木: リーフノードを除くすべてのノードには 2 つの子があります。
  3. 完全二分木: すべてのリーフ ノードが同じ深さまたは同じレベルにあり、各親ノードには 2 つの子ノードが存在するという特性を持つ完全な二分木。
  4. 完全な二分: 二分木では、最後のレベルを除いて各レベルが完全に埋められ、すべてのノードは可能な限り左に配置されている必要があります。

翻訳者注: 完全二分木は、漠然と完全二分木とも呼ばれます。完全な二分木の例としては、特定の深さにある人の祖先グラフが挙げられます。これは、すべての人が 2 人の生物学的な親を持つ必要があるためです。完全な二分木は、左側にいくつかの追加の葉ノードがある完全な二分木として見ることができます。質問: 完全二分木と完全二分木の違いは何ですか? (参考: http://xlinux.nist.gov/dads/HTML/perfectBinaryTree.html)

#p#

4. グラフ

グラフ関連の問題は、主に深さ優先探索と呼吸優先探索に焦点を当てています。

以下はグラフ上の幅優先探索の簡単な実装です。

1) GraphNodeを定義する

  1. クラスGraphNode{
  2. 整数値;
  3. GraphNode 次;
  4. GraphNode[] の隣接ノード;
  5. ブール値訪問済み;
  6.   
  7. グラフノード( int x) {
  8. val = x;
  9. }
  10.   
  11. グラフノード( int x, グラフノード[] n){
  12. val = x;
  13. 近隣 = n;
  14. }
  15.   
  16. パブリック文字列toString(){
  17. 戻る  "値: " + this .val;
  18. }
  19. }

2) キューを定義する

  1. クラスQueue{
  2. GraphNode 最初、最後;
  3.   
  4. 公共  void enqueue(GraphNode n){
  5. if (first == null ){
  6. 最初 = n;
  7. 最後 = 最初;
  8. }それ以外{
  9. 最後.次 = n;
  10. 最後 = n;
  11. }
  12. }
  13.   
  14. パブリックGraphNodeデキュー(){
  15. if (first == null ){
  16. 戻る ヌル;
  17. }それ以外{
  18. GraphNode temp = new GraphNode(first.val, first.neighbors);
  19. 最初 = first.next;
  20. 温度を返します
  21. }
  22. }
  23. }

3) キューを使用して幅優先探索を実装する

  1. 公共 クラスGraphTest {
  2.   
  3. 公共 静的  void main(String[] args) {
  4. グラフノード n1 =新しいグラフノード( 1 );
  5. グラフノード n2 =新しいグラフノード( 2 );
  6. グラフノード n3 =新しいグラフノード( 3 );
  7. グラフノード n4 =新しいグラフノード( 4 );
  8. グラフノード n5 =新しいグラフノード( 5 );
  9.   
  10. n1.neighbors =新しいGraphNode[]{n2,n3,n5};
  11. n2.neighbors =新しいGraphNode[]{n1,n4};
  12. n3.neighbors =新しいGraphNode[]{n1,n4,n5};
  13. n4.neighbors =新しいGraphNode[]{n2,n3,n5};
  14. n5.neighbors =新しいGraphNode[]{n1,n3,n4};
  15.   
  16. ブレスファーストサーチ(n1, 5 );
  17. }
  18.   
  19. 公共 静的  void呼吸ファーストサーチ(グラフノードルート、 int x){
  20. (root.val == x)の場合
  21. System.out.println( "ルート内で検索" );
  22.   
  23. キュー queue = new Queue();
  24. ルートが訪問済み = true ;
  25. キューをエンキューします(ルート);
  26.   
  27. (queue.first != null ) {
  28. GraphNode c = (GraphNode) queue.dequeue();
  29. (GraphNode n: c.neighbors)の場合{
  30.   
  31. 訪問した場合
  32. System.out.print(n + " " );
  33. n.visited = true ;
  34. (n.val == x)の場合
  35. System.out.println( "検索 " +n);
  36. キューをエンキューします。(n);
  37. }
  38. }
  39. }
  40. }
  41. }

出力:

  1. 値: 2値: 3値: 5値を検索: 5  
  2. 値: 4

5. ソート

以下は、さまざまなソート アルゴリズムの時間計算量です。これらのアルゴリズムの基本的な考え方については、Wiki を参照してください。

アルゴリズム平均時間最悪の時期空間
バブルソート2乗2乗1
選択ソート2乗2乗1
カウントソートん+kん+kん+k
挿入ソート2乗2乗
クイックソートn 対数(n) 2乗
マージソートn 対数(n) n 対数(n)依存する

また、いくつかの実装/デモがあります: Counting sort、Mergesort、Quicksort、InsertionSort。

  • 《よく使われる7つのソートアルゴリズムを視覚的に直感的に体験》
  • 《ビデオ: 6 分で 15 種類のソートアルゴリズムを解説》

#p#

6. 再帰と反復

プログラマーにとって、再帰は組み込みの考え方であるべきであり、簡単な例で説明できます。

質問: 階段には n 段あり、一度に 1 段または 2 段しか上れません。階段を上る方法は何通りありますか?

ステップ 1: 最初の n ステップと最初の n-1 ステップの関係を見つけます。

n 段を歩くには、n-1 段目から 1 段登るか、n-2 段目から 2 段登るかの 2 つの方法しかありません。 f(n) が n 番目のステップに登る方法の数である場合、f(n) = f(n-1) + f(n-2) となります。

ステップ 2: 開始条件が正しいことを確認します。

0 = 0;

1 = 1;

  1. 公共 静的  int f( int n){
  2. n <= 2場合はn を返します
  3. 整数x = f(n- 1 ) + f(n- 2 );
  4. xを返します
  5. }

再帰法の時間計算量は、次のように冗長な計算が多いため、n に対して指数関数的に増加します。

5 倍
f(4) + f(3)
f(3) + f(2) + f(2) + f(1)
f(2) + f(1) + f(1) + f(0) + f(1) + f(0) + f(1)
f(1) + f(0) + f(1) + f(1) + f(0) + f(1) + f(0) + f(1)

単純なアイデアは、再帰を反復に変換することです。

  1. 公共 静的  int f( int n) {
  2.   
  3. (n <= 2 )の場合{
  4. nを返します
  5. }
  6.   
  7. int最初 = 1 、 2 番目 = 2 ;
  8. 整数3番目 = 0 ;
  9.   
  10. ( int i = 3 ; i <= n; i++)の場合{
  11. 3番目 = 1番目 + 2番目;
  12. 最初 = 2番目;
  13. 2番目 = 3番目;
  14. }
  15.   
  16. 3番目を返します
  17. }

この例では、反復処理にかかる時間が短くなります。再帰と反復処理も確認することをお勧めします。

7. 動的プログラミング

動的プログラミングは、次のような性質の問題を解決するための手法です。

問題は、より小さなサブ問題の解決によって解決できます。

いくつかのサブ問題の解は複数回計算する必要がある場合があります (翻訳者注: これはサブ問題の重複性によるものです)。

サブ問題の解はテーブルに保存されるため、各サブ問題は 1 回だけ計算すれば済みます。

時間を節約するには余分なスペースが必要です。

階段登り問題は上記の 4 つの特性を完全に満たしているため、動的計画法で解決できます。

  1. 公共 静的  int [] A =新しい 整数[ 100 ];
  2.   
  3. 公共 静的 整数f3(整数n){
  4. (n <= 2 )の場合
  5. A[n] = n;
  6.   
  7. もし(A[n] > 0 )
  8. A[n]を返す
  9. それ以外 
  10. A[n] = f3(n- 1 ) + f3(n- 2 ); // 結果を保存して一度だけ計算します。  
  11. A[n]を返す
  12. }

8. ビット操作

ビット演算子:

または (|)そして (&)排他的論理和 (^)左シフト (<<)右シフト (>>)ない(〜)
1|0=1 1&0=0 1^0=1 0010<<2=1000 1100>>2=0011 ~1=0

指定された数値 n の i 番目の桁を取得します (i は 0 から数えられ、右から始まります)

  1. 公共 静的 ブール型getBit( int num, int i){
  2. int結果 = num & ( 1 << i );
  3.   
  4. 結果 == 0場合
  5. 戻る 間違い;
  6. }それ以外{
  7. 戻る 真実;
  8. }

たとえば、数字 10 の 2 番目の数字を取得するには、次のようにします。

i=1, n=10
1<<1= 10
1010&10=10
10 は 0 ではないので、true を返します。

9. 確率の問題

確率の問題を解くには、通常、問題を適切にフォーマットする必要があります。次に、そのような問題の簡単な例を示します。

部屋には 50 人がいます。そのうち少なくとも 2 人が同じ誕生日である確率はどれくらいでしょうか。 (うるう年を無視すると、1年は365日です)

何かの確率を計算することは、多くの場合、まずその逆を計算することに変換できます。この例では、すべての人が異なる誕生日である確率を計算できます。これは、365/365 + 364/365 + 363/365 + 365-n/365 + 365-49/365 となり、少なくとも 2 人の誕生日が同じである確率は、1 - この値になります。

  1. 公共 静的 ダブル計算確率( int n){
  2. ダブルx = 1 ;
  3.   
  4. ( int i = 0 ; i < n; i++) {
  5. x * = ( 365.0 -i) / 365.0 ;
  6. }
  7.   
  8. ダブルプロ = Math.round(( 1 -x) * 100 );
  9. pro/ 100を返します

確率を計算する(50) = 0.97

10. 順列と組み合わせ

組み合わせと順列の違いは、順序が重要かどうかです。

オリジナルリンク: http://www.programcreek.com/2012/11/top-10-algorithms-for-coding-interview/

翻訳リンク: http://blog.jobbole.com/52144/

<<:  通信ネットワークにおけるOSPFプロトコルの適用とアルゴリズムの最適化

>>:  IBC識別パスワードSM9アルゴリズムに基づくID認証ソリューション

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

エンティティと値オブジェクトの特性を識別する

[[411622]]正確さは集計の設計に直接影響するため、エンティティと値オブジェクトを区別すること...

「とんでもないAI画像拡大」が流行ってる!張張、それは驚きだ

家族、Tik TokのAI拡大画像に本当に笑い死にしそう——観た後に「意外」で「すごく怒る」というの...

自動監視、リアルタイム警報AI防水システムが安全ネットを構築

暑い夏には、スーパーマーケットにちょっとしたおやつを買いに行くだけでも大量の汗をかきます。扇風機を使...

転移学習に使用される 4 つのコンピュータ ビジョン フィールド モデル

導入SOTA 事前トレーニング済みモデルを使用して、転移学習を通じて現実世界のコンピューター ビジョ...

販売禁止の影で、国産GPGPUがその穴を埋めることはできるのか?

今年初め、ChatGPTはAIアプリケーションの開発を刺激する火花のようなもので、AI業界は開発の急...

PyTorch を使用した Mixture of Experts (MoE) モデルの実装

Mixtral 8x7B の発売は、オープン AI の分野、特に Mixture-of-Expert...

2030 年までに人工知能はどのようになるでしょうか?

[[378797]]画像ソース: unsplashマッキンゼー・グローバル・インスティテュートの調...

C# はデジタル変換のための中国語アルゴリズムを記述します

C# はデジタル変換のための中国語アルゴリズムを記述します最近、プロジェクト上の理由により、C# で...

毎日のアルゴリズム: 上位 K 個の高頻度要素

空でない整数の配列が与えられた場合、最も頻繁に出現する上位 k 個の要素を返します。例1:入力: n...

...

AI、VR、ブロックチェーンにより、新しい時代は貧しい人々にとっての楽園となるのでしょうか?

今日の社会では貧困がまだ存在しています。 [[275832]]国連開発計画(UNDP)のデータによる...

機械学習がサイバー脅威に対する最善の武器である理由

攻撃対象領域が拡大し続け、攻撃手法がより高度化するにつれ、セキュリティ業界は現在、深刻な「セキュリテ...

Jia Jiayaのチームが世界初の70B長文大規模言語モデルをオープンソース化し、ProMaxを使って論文や小説を直接読めるようにした。

皆さん、大規模言語モデル(LLM)の長年の課題がついに解決されました!つい最近、香港中文大学とMIT...

ディープラーニング入門

2016年、Googleの人工知能プログラムAlphaGoが世界的囲碁プレイヤーのイ・セドルと対戦し...

Google が TensorFlow Lite を Play サービスに導入

近年、大手テクノロジー企業は人工知能と機械学習の研究に力を入れています。その中でも、Googleはこ...