次のようにルビー再帰アルゴリズム問題
def words_typing(sentence, rows, cols)
count_words(sentence, rows, cols, cols, 0, 0)
end
def count_words(sentence, rows, cols, remaining_space, row_num, word_idx)
return 0 if row_num == rows #keep going until out of rows, ends the recursion
word_idx = 0 if word_idx == sentence.length #reset the word back to the first
if remaining_space >= sentence[word_idx].length
if remaining_space == sentence[word_idx].length
return 1 + count_words(sentence, rows, cols, remaining_space - sentence[word_idx].length, row_num, word_idx + 1)
else #greater than 1
return 1 + count_words(sentence, rows, cols, remaining_space - sentence[word_idx].length - 1, row_num, word_idx + 1)
end
else #move to a new line, reset remaining space
return count_words(sentence, rows, cols, cols, row_num+1, word_idx)
end
end
コードは動作します:
はGiven a rows x cols screen and a sentence represented by a list of non-empty words, find how many times the given sentence can be fitted on the screen.
Note:
A word cannot be split into two lines.
The order of words in the sentence must remain unchanged.
Two consecutive words in a line must be separated by a single space.
Total words in the sentence won't exceed 100.
Length of each word is greater than 0 and won't exceed 10.
1 ≤ rows, cols ≤ 20,000.
Example 1:
Input:
rows = 2, cols = 8, sentence = ["hello", "world"]
Output:
1
Explanation:
hello---
world---
The character '-' signifies an empty space on the screen.
Example 2:
Input:
rows = 3, cols = 6, sentence = ["a", "bcd", "e"]
Output:
2
Explanation:
a-bcd-
e-a---
bcd-e-
The character '-' signifies an empty space on the screen.
Example 3:
Input:
rows = 4, cols = 5, sentence = ["I", "had", "apple", "pie"]
Output:
1
Explanation:
I-had
apple
pie-I
had--
The character '-' signifies an empty space on the screen.
ここに私のコードです。 word_idxは、文の配列内の単語のインデックスです。残りのスペースは、最初は列の数です。単語が置かれるのに十分なスペースがあるときは、次の単語とスペースが残っている同じ行の関数呼び出しを返します。残りのスペース> = 1 +単語の長さの場合、2つの連続した単語の間にスペースがあることを考慮します(これが理由で余分な条件付きです)。
word_idxが文の配列よりも長くなると、必要に応じて0にリセットされます。再帰関数は、row_numが問題で私たちに提供されている行の数より大きくなるまで継続します。
ただし、このコードは機能しません。私のアウトプットは正解よりも大きいのですが、概念的には私にとっては大丈夫です。誰か私のアプローチに何か間違っているのを見ますか?
大変ありがとうございます。これはほとんどの入力に対して機能します。しかし、大規模なテストケースでは、スタックが深すぎるというエラーが発生します。私は理由を理解しようとしています。単語を正しい方法で置くことができるかどうかに応じて、ただ1つの再帰呼び出しを行います。アルゴリズムは他の場所では効率が悪いのですか? – Sunny
@Sunnyあなたは、それぞれのフィットワード+ 1つにつき1回の再帰呼び出しを行います。例えば#1(行= 3、列= 6、文= [a、bcd、e])= 10のコール、例#2(行= 4、列= 5、文= [I、had、apple、pie ])= 11コール。そして、Rubyは(私はRubyの現在の状態を知らない)非常に機能的ではないので、あまり再帰を使わないでください。スタックレベルを上げるか、「テールコールの最適化」を有効にすることができます(この場合は有効かどうかはわかりません)。ここでそれを説明する素晴らしいリンクですhttp://rpanachi.com/2016/05/30/ruby-recursion-stack-size-tail-call-optimization –