データ構造とアルゴリズムの比較 バックスペースを含む文字列!

データ構造とアルゴリズムの比較 バックスペースを含む文字列!

[[441739]]

バックスペースで文字列を比較する

LeetCode の問題へのリンク: https://leetcode-cn.com/problems/backspace-string-compare

2 つの文字列 S と T がそれぞれ空のテキスト エディターに入力された場合、2 つの文字列が等しいかどうかを判定し、結果を返します。 # はバックスペース文字を表します。

注意: 空のテキストにバックスペース文字を入力すると、テキストは空のままになります。

例1:

  • 入力: S = "ab#c"、T = "ad#c"
  • 出力: true
  • 説明: S と T は両方とも「ac」になります。

例2:

  • 入力: S = "ab##", T = "c#d#"
  • 出力: true
  • 説明: S と T は両方とも "" になります。

例3:

  • 入力: S = "a##c"、T = "#a#c"
  • 出力: true
  • 説明: S と T は両方とも「c」になります。

例4:

  • 入力: S = "a#c"、T = "b"
  • 出力: false
  • 説明: S は「c」になりますが、T は「b」のままです。

アイデア

この記事では、空間計算量を伴うスタック シミュレーション方式と空間計算量を伴うダブル ポインター方式について説明します。

通常の方法(スタックの考え方を使用)

この問題では、明らかにスタックを使用する必要があります。この種のマッチング (消去) 問題も、スタックが得意とする分野です。私と一緒に学習する学生は、スタックとキューにおけるマッチング問題がスタックの強みであることを理解する必要があります。同様のことを行うためにスタックを使用することについては、すでに一度触れました。

したがって、この問題では、スタックの考え方を実際に使用できますが、最後に比較するときにスタック内の要素も比較する必要があるため、スタックを使用する必要はありません。これは少し面倒です。

ここでは、文字列をそのままスタックとして使用し、最後に追加とポップを行い、文字列には対応するインターフェースがあります。最後に比較するときは、2 つの文字列を比較するだけで済み、スタック内の要素を比較するよりも便利です。

コードは次のとおりです。

  1. クラスソリューション{
  2. 公共
  3. bool backspaceCompare(文字列S、文字列T) {
  4. string s; // スタックとして使用
  5. string t; ​​// スタックとして使用
  6. ( int i = 0; i < S.size ( ); i++) {
  7. S[i] != '#'の場合、 s += S[i];
  8. それ以外の場合 (!s.empty()) {
  9. s.pop_back();
  10.  
  11. }
  12. ( int i = 0; i < T.size ( ) ); i++) {
  13. T[i] != '#'の場合、t += T[i];
  14. それ以外の場合は (!t.empty()) {
  15. t.pop_back();
  16. }
  17. }
  18. (s == t)の場合、戻り値  true ; // 2つの文字列が等しいかどうかを直接比較する方が、スタックを使用するよりもはるかに便利です
  19. 戻る 間違い;
  20. }
  21. };

時間計算量: nはSの長さ、mはTの長さであり、時間計算量とも言える。

空間計算量: もちろん、上記のコードでは、処理 S と処理 T の繰り返しロジックがあることがわかります。この共通ロジックを抽出して、コードを次のように簡略化できます。

  1. クラスソリューション{
  2. プライベート:
  3. 文字列 getString(const string& S) {
  4. 文字列 s;
  5. ( int i = 0; i < S.size ( ); i++) {
  6. S[i] != '#'の場合、 s += S[i];
  7. それ以外の場合 (!s.empty()) {
  8. s.pop_back();
  9. }
  10. }
  11. sを返します
  12. }
  13. 公共
  14. bool backspaceCompare(文字列S、文字列T) {
  15. getString(S) == getString(T)を返します
  16. }
  17. };

パフォーマンスは依然として次のとおりです。

  • 時間の計算量:
  • 空間の複雑さ:

最適化方法(後ろから前へのダブルポインタ)

もちろん、この問題を解決するために使用する空間計算量もあります。

同時に、S と T を後ろから前へトラバースし (i は最初は S の末尾にあり、j は最初は T の末尾にあります)、# の数を記録し、消去操作をシミュレートし、# が使い果たされた場合は、S[i] と S[j] の比較を開始します。

アニメーションは次のとおりです。

S[i]とS[j]が同じでない場合は、falseが返されます。一方のポインタ(iまたはj)が最初に文字列の先頭に到達した場合も、falseが返されます。

コードは次のとおりです。

  1. クラスソリューション{
  2. 公共
  3. bool backspaceCompare(文字列S、文字列T) {
  4. int sSkipNum = 0; // Sの数を記録する
  5. int tSkipNum = 0; // Tの数を記録する
  6. int i = S.size ( ) - 1;
  7. int j = T.size ( ) - 1;
  8. 一方(1){
  9. while (i >= 0) { // 後ろから前へ、S# を削除します
  10. S[i] == '#'の場合、 sSkipNum++;
  11. それ以外{
  12. sSkipNum > 0 の場合、 sSkipNum --;  
  13. そうでなければ中断します。
  14. }
  15. 私 - ;  
  16. }
  17. while (j >= 0) { // 後ろから前に向かってTを削除します #
  18. T[j] == '#'の場合、tSkipNum++;
  19. それ以外{
  20. tSkipNum > 0 の場合、tSkipNum --;  
  21. そうでなければ中断します。
  22. }
  23. j --;  
  24. }
  25. // 後半の半分# は削除され、S[i] != T[j] と比較されます
  26. if (i < 0 || j < 0) break; // S または T がトラバーサルの終了に到達しました
  27. (S[i] != T[j]) の場合、戻り値 間違い;
  28. 私は--;j--;  
  29. }
  30. // SとTが同時に走査されることを示します
  31. (i == -1 && j == -1)の場合、戻り値 真実;
  32. 戻る 間違い;
  33. }
  34. };
  • 時間の計算量:
  • 空間の複雑さ:

その他の言語

ジャワ:

  1. // 通常のメソッド(スタックの考え方を使用)
  2. クラスソリューション{
  3. パブリックブールバックスペース比較(文字列s、文字列t) {
  4. StringBuilder ssb = new StringBuilder(); // スタックをシミュレートする
  5. StringBuilder tsb = new StringBuilder(); // スタックをシミュレートする
  6. // 2つの文字列を別々に処理する
  7. ( char c : s.toCharArray())の場合{
  8. (c != '#' )の場合{
  9. ssb.append(c); // スタッキングをシミュレートする
  10. } else if (ssb.length() > 0){ // スタックをポップするにはスタックが空でない必要がある
  11. ssb.deleteCharAt(ssb.length() - 1); // スタックのポップをシミュレートする
  12. }
  13. }
  14. ( char c : t.toCharArray())の場合{
  15. (c != '#' )の場合{
  16. tsb.append(c); // スタッキングをシミュレートする
  17. } else if (tsb.length() > 0){ // スタックをポップするにはスタックが空でない必要がある
  18. tsb.deleteCharAt(tsb.length() - 1); // スタックのポップをシミュレートする
  19. }
  20. }
  21. ssb.toString().equals(tsb.toString());を返します
  22. }
  23. }

パイソン

  1. クラスソリューション:
  2.  
  3. get_string(self, s: str) を定義します。
  4. bz = []
  5. i が範囲(len(s))内にある場合:
  6. c = s[i]
  7. c != '#'の場合:
  8. bz.append(c) # スタッキングをシミュレートする
  9. elif len(bz) > 0: # スタックをポップするにはスタックが空でない必要があります
  10. bz.pop() # スタックのポップをシミュレートする
  11. str(bz)を返す
  12.  
  13. def backspaceCompare(self, s: str, t: str) -> bool:
  14. self.get_string(s) == self.get_string(t)を返します
  15. 合格

行く

  1. getString関数(文字列)文字列{
  2. bz := []ルーン{}
  3. _の場合、c := 範囲 s {
  4. c != '#'の場合{
  5. bz = append(bz, c); // スタッキングをシミュレートする
  6. } else if len(bz) > 0 { // スタックをポップするにはスタックが空でない必要がある
  7. bz = bz[:len(bz)-1] // スタックポップをシミュレートする
  8. }
  9. }
  10. 文字列を返す(bz)
  11. }
  12.  
  13. func backspaceCompare(s 文字列, t 文字列) bool {
  14. getString(s) == getString(t)を返します
  15. }

JavaScript

  1. //デュアルスタック
  2.  
  3. var backspaceCompare =関数(s, t) {
  4.  
  5. const arrS = [], arrT = []; // スタックとして使用される配列
  6.  
  7. (let charの場合 ){
  8.  
  9. char === '#' ? arrS.pop() : arrS.push( char );
  10.  
  11. }
  12.  
  13. (let charの場合  t ){の
  14.  
  15. char === '#' ? arrT.pop() : arrT.push( char );
  16.  
  17. }
  18.  
  19. return arrS.join ( '' ) === arrT.join ( ' ' ) ; // 2つの文字列が等しいかどうかを比較する
  20.  
  21. };
  22.  
  23. //デュアルスタックの簡素化
  24.  
  25. var backspaceCompare =関数(s, t) {
  26.  
  27. 定数getString = s => {
  28.  
  29. arrS = [] とします。
  30.  
  31. (let charの場合 ){
  32.  
  33. char === '#' ? arrS.pop() : arrS.push( char );
  34.  
  35. }
  36.  
  37. arrS.join ( '' )を返します
  38.  
  39. }
  40.  
  41. getString(s) === getString(t) を返します
  42.  
  43. };
  44.  
  45. //ダブルポインタ
  46.  
  47. var backspaceCompare =関数(s, t) {
  48.  
  49. let sSkipNum = 0; // sの数を記録する
  50.  
  51. let tSkipNum = 0; // tの数を記録する
  52.  
  53. i = s.length - 1、j = t.length - 1とします。
  54.  
  55. while( true ) {
  56.  
  57. while(i >= 0){ // 後ろから前へ、s# を削除します
  58.  
  59. s[i] === '#'の場合、 sSkipNum++;
  60.  
  61. それ以外{
  62.  
  63. sSkipNum > 0 の場合、 sSkipNum --;  
  64.  
  65. そうでなければ中断します。
  66.  
  67. }
  68.  
  69. 私 - ;  
  70.  
  71. }
  72.  
  73. while (j >= 0) { // 後ろから前へ、t# を削除します。
  74.  
  75. t[j] === '#'の場合、tSkipNum++;
  76.  
  77. それ以外{
  78.  
  79. tSkipNum > 0 の場合、tSkipNum --;  
  80.  
  81. そうでなければ中断します。
  82.  
  83. }
  84.  
  85. j --;  
  86.  
  87. }
  88.  
  89. // 後半の半分# は削除され、s[i] != t[j] と比較されます
  90.  
  91. if (i < 0 || j < 0) break; // s または t が走査の終わりに到達しました
  92.  
  93. s[i] !== t[j] の場合、戻り値 間違い;
  94.  
  95. 私は--;j--;  
  96.  
  97. }
  98.  
  99. // s と t が同時に走査されることを示します
  100.  
  101. (i == -1 && j == -1)の場合、戻り値 真実;
  102.  
  103. 戻る 間違い;
  104.  
  105. };

<<:  知っておくべき6つのAIバイアス

>>:  クリスマスのギフトボックスにロボット犬を見つけますか?ボストン・ダイナミクスがイースターエッグをリリースしたが、ギフトボックスが逃げてしまった

ブログ    
ブログ    
ブログ    

推薦する

インターネットの価値観を修正するガバナンスアルゴリズム

最近、中国サイバースペース管理局は「インターネット情報サービスアルゴリズム推奨管理規則(草案)」(以...

AIは病気の診断や新薬の設計に大きな可能性を秘めている

ヘルスケア業界は常にイノベーションの先駆者であり続けています。しかし、病気やウイルスが変異し続ける中...

ChatGPTは来週Androidでリリースされ、事前登録が開始されました

ChatGPTは来週Android版をリリースすることを公式に発表し、Google Playストアで...

...

...

生成 AI とビッグモデルの違いと関連性は何ですか?

近年、ChatGPT、GPT-4、BARD、Claudeなどの大規模モデルが急速かつ大幅な進歩を遂げ...

ディズニーは強化学習を利用して新しいロボットをスターウォーズ風に仕上げた

ディズニーの新しいロボットがデビュー!では早速、どんな感じか見てみましょう——大きく輝く目、揺れる頭...

ドローンによるマッピング:建設業界の再考

[[392894]]建設業界は技術変革の瀬戸際に立っています。建設業界では新しい技術の導入が遅れるこ...

機械学習を通じて実際のビジネス価値を掘り出すにはどうすればよいでしょうか?

運用効率の向上から継続的なイノベーションの実現まで、機械学習はビジネス開発に不可欠なものとなっていま...

Upscayl、最先端のAI画像拡大技術

デジタル時代では、画像はどこにでもあります。ソーシャル メディアで写真を共有する場合でも、ビジネスの...

AI アルゴリズムがハードウェアを置き換えることは可能でしょうか?

Googleは2021年末にPixel 6シリーズの携帯電話をリリースした際、携帯電話に心拍数モニ...

AIを活用した臨床モニタリングシステムの台頭

[[355709]]現在、医療システムもさまざまな方法で人工知能の利点を取り入れています。人工知能(...

AIの4つのタイプについてお話しましょう

人工知能が流行するにつれ、人々はそれがどのように機能し、何ができるのかについて多くの疑問を抱いていま...

AIが初めて新型コロナウイルスの警告を発するのか?人工知能はあなたが思っている以上に信頼できるものです!

2019年12月30日に武漢で新型肺炎が発生してから1か月以上が経ちました。マスクの値上げや品切れ...