動的プログラミングとJava実装の一般的な問題解決のアイデア

プロジェクト紹介

  • このプロジェクトは、主要な工場の一般的な筆記面接の質問を分解し、データ構造とアルゴリズムの基礎となる実装原理までソースをたどり、それらが何であるかを知っています。
  • 簡単な検索のための知識構造システムを確立し、志を同じくする友人をプロジェクトAlgorithmPracticeに参加するように歓迎します(問題とプルリクエストは歓迎されます)。

パート1:小さなテスト

コンテンツのこの部分では、いくつかの比較的単純な動的プログラミングのトピックを選択して、動的プログラミングとは何かを徐々に理解しました。

パート2:紹介する

コンテンツのこの部分は基本的なソリューションのみを提供します。より最適化されたソリューションがある場合は、以下のメッセージを残してください。

パート3:包括的なハイライト

コンテンツのこの部分のソリューションは、貪欲、バックトラックなどを含む動的プログラミングに限定されません。

テキストの始まり

1.カエルが階段を飛び越える

  • タイトルの説明:階段を上るときは、1つまたは2つの階段を上るたびに、n段の階段がいくつあるか尋ねます。
  • コードの実装:ClimbStairs、テストケース:ClimbStairsTest
  • デザインのアイデア:
    • 状態遷移方程式:
statusNum[i] = statusNum[i-1] + statusNum[i-2];
  • 予防:
    • 頻繁にアクセスするデータについては、キャッシュを設定して読みやすくすることができます。

2.最大のサブセグメント合計

  • タイトルの説明:配列を指定して、この配列の連続するサブ配列の最大セグメントの合計を見つけます
  • コードの実装:LSS、テストケース:LSSTest
  • デザインのアイデア:
  • 動的計画法:
状态转换方程:
LargestSum[i] = Math.max(LargestSum[i-1] + Sequence[i], Sequence[i]);
  • 動的プログラミング最適化方法:
for(int i = 1; i < Sequence.length; i++){
    
    
	sum_temp += Sequence[i];
	if(sum_temp <= Sequence[i]){
    
      //新开始
		sum_temp = Sequence[i];   //sum清空
		begin_temp = i;           //假定的起始位置
	}
	if(sum < sum_temp){
    
    
		sum = sum_temp;           //记录最大值
		begin = begin_temp;       //假定的起始地址赋值给起始地址
		end = i;                  //结束地址包括 i
	}
}
  • 分割統治:
int leftValue = divide(Sequence, left, mid);
int rightValue = divide(Sequence, mid + 1, right);
int midValue = mid(Sequence, left, right);
  • 予防:

3.最長の共通サブシーケンス

  • タイトルの説明:2つの文字列のうち一致する最大の部分文字列を検索します
  • コードの実装:LCS、テストケース:LCSTest
  • デザインのアイデア:
    • 状態遷移方程式:
num_matrix[row][column] = num_matrix[row-1][column-1]+1;
num_matrix[row][column] = num_matrix[row-1][column];
num_matrix[row][column] = num_matrix[row][column-1];
  • 予防:

4.回文アプリケーション(回文)

4.1。文字列が回文に属しているかどうかを判断する

  • タイトルの説明:指定された文字列が回文かどうかを判断します。デフォルトでは、単一の文字では回文を作成するのに十分ではありません
  • コード:
public boolean PalindromeJudge(String testString) {
    
    
	if(testString == null || testString.length() == 0){
    
    
		return false;
	}
	boolean flag = new StringBuffer(testString).reverse().toString().equals(testString);
	return flag;
}
  • デザインアイデア:文字列を反転して一致させる
  • 予防:
4.2。キャラクターを追加して回文を構成する

  • タイトルの説明:文字列sを指定すると、そこから文字を追加して、残りの文字列を回文にすることができます。文字を追加して回文を取得した場合は、追加した要素の位置を返します(開始アドレス:1) 、それ以外の場合は-1を返し、パリンドロームの場合は中央の位置を返します
  • コードの実装:CreatePalindromebyAdd、テストケース:CreatePalindromebyAddTest
  • デザインのアイデア:
  • 予防:
4.3、パリンドロームを構築するためにいくつかの文字を削除します

  • タイトルの説明:文字列sを指定すると、その文字をいくつか削除して、残りの文字列を回文にすることができます。回文を最長にするために削除する方法は?削除する文字数を出力
  • コードの実装:CreatePalindromebyDelete、テストケース:CreatePalindromebyDeleteTest
  • デザインアイデア:文字列が逆になり、最大類似数がLCSアルゴリズムによって計算されます。次に、類似していない数を削除する必要があります。
  • 予防:
4.4。与えられた文字列で最も長い連続パリンドロームの部分文字列を見つける

  • タイトル説明:
  • コードの実装:FindPalindrome、テストケース:FindPalindromeTest
    • 4.4.1、暴力法
    • 4.4.2、中央拡散法
    • 4.4.3、Manacherアルゴリズム
  • デザインのアイデア:
    • 4.4.1、暴力法
    • 4.4.2、中央拡散法
    • 4.4.3、Manacherアルゴリズム
  • 予防:

5.最短の配送パス

  • トピックの説明:
    物流配達員pは、4つのエクスプレスポイントa、b、c、dに荷物を配達する必要があります。最短配達を完了するには、配達員がどのルートを選択する必要がありますか。図に示すように、ディスパッチャーの開始点座標(0,0)を想定すると、ディスパッチングルートは、図の正方形の辺に沿ってのみ移動でき、小さな正方形はそれぞれ正方形で、辺の長さは1です(pからdまでの距離は4など)。 。ランダムにn個の配送ポイントの座標を入力し、最短の配送ルートの値(出発地点からnポイントの配送を完了して出発地点に戻るまでの距離)を見つけます。
    ここに画像の説明を挿入
  • コード:
  • デザインのアイデア:
    • お元気ですか
    • バックトラック
  • 予防:

6.最適なスケジューリング問題

  • タイトルの説明:並行して動作できるk台のマシンが完了するn個のタスクがあり、タスクiを完了するのに必要な時間はtasksspendTimeです。これらのn個のタスクを完了するための最適なスケジュールを見つけるアルゴリズムを設計して、すべてのタスクを完了する時間が最も早くなるようにしてください
  • コードの実装:OptimalSchedule、テストケース:OptimalScheduleTest
  • デザインのアイデア:
  • 予防:

7.最も長く増加するサブシーケンス

  • タイトルの説明:与えられた数値シーケンスで、このサブシーケンスの要素の値が順次増加し、このサブシーケンスの長さができるだけ長くなるように、サブシーケンスを見つけます。最も長く増加するサブシーケンスの要素は、元のシーケンスで必ずしも連続しているとは限りません
  • コードの実装:LIS、テストケース:LISTest
  • デザインのアイデア:
  • 予防:

8.最大の正方形

9.距離を編集する

  • タイトルの説明:
    編集距離とは、2つの単語間で1つの単語を別の単語に変換するために必要な1文字の編集操作の最小数を指します。ここでは、挿入、削除、置換の3つの単一文字編集操作しかありません。
    たとえば、「子猫」と「座っている」という2つの単語は、「子猫」から「座っている」に変換されます。 「最低限必要な1文字の編集操作は、次のとおり
    です。1.子猫→座っている(「s」を「k」に
    置き換え2.座っている→座っている(「i」を「e」に置き換える)
    3.座っている→座っている(挿入末尾の「G」)
    したがって、「子猫」と「座っている」という単語の間の編集距離は3です。
  • コードの実装:EditDistance、テストケース:EditDistanceTest
  • デザインのアイデア:
    • 状態遷移方程式:
if (c1[i-1] == c2[j-1]) {
    
    
  comp[i][j] = comp[i - 1][j - 1];
} else {
    
    
  comp[i][j] = Math.min(Math.min(comp[i - 1][j - 1], comp[i][j - 1]), comp[i - 1][j]) + 1;
}
  • 予防:

a、バックパック問題(バックパック)

  • タイトル説明:
  • コードの実装:バックパック、テストケース:
  • デザインのアイデア:
  • 予防:

b。合唱団

  • タイトルの説明:n人の生徒が並んでいて、各生徒には能力値があります。NiNiuはこれらのn人の生徒から順にChoseNum生徒を選択したいと考えています。隣接する2人の生徒の位置番号の差はd以下なので、 ChoseNumの生徒の能力値の積が最大です。最大の積を返せますか?
  • コード:
  • デザインのアイデア:
    • 動的プログラミング:
    • バックトラック方法:
  • 予防:

おすすめ

転載: blog.csdn.net/ljfirst/article/details/103082359