leetcode : Valid_Parentheses
こんにちは、かずとよです。
今回もleetcode。
まずは問題文が以下。
Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
Example 1:
Input: s = "()" Output: true
Example 2:
Input: s = "()[]{}"
Output: true
Example 3:
Input: s = "(]" Output: false
Example 4:
Input: s = "([)]" Output: false
Example 5:
Input: s = "{[]}"
Output: true
Constraints:
1 <= s.length <= 104sconsists of parentheses only'()[]{}'.
簡単に解読すると
【与えられる文字列は、"(", ")", "{", "}", "[", "]" これら3種類の括弧のみ。
正しく使えているか判別しよう。】
ということみたい。
例1)"(" は ")" で閉じるのは、もちろんOK。
例3)"(" を "]" で閉じるのはダメ。
例4)最初と閉じとがおかしい。
みたいな感じですね。
ぶっちゃけ今回の問題、昨日から始めたのに、解けなさすぎて頭痛がやばくなって寝ました。
で、一旦コードから離れて、リフレッシュして、再挑戦!
・・・それでも解けなくて、他の人のコード見ました。
理解するまで読み込んで、勉強しました。
やっと理解できて自分でコード書けたので、アウトプット!
まずは、僕が最初書いてた、ダメダメコード↓↓
def is_valid(s) x = s.match(/(\((\]|\}))|(\[(\)|\}))|(\{(\)|\]))/) y = s.match(/\(\)|\[\]|\{\}/) z = s.match(/\)\(|\]\[|\}\{/) start_c = s.count("([{") end_c = s.count(")]}") if s.length == 1 return false elsif x.to_s.length >= 2 return false elsif y == nil return false elsif z.to_s.length >= 2 return false elsif start_c == end_c return true end end
ここまで、10回以上トライアンドエラーを繰り返してます。
ひとつクリアできても、次に出てくるテスト内容で引っかかるから、elseif増やして・・・みたいな感じで。
この後も、複数回これを繰り返しました。ほんとキリがないし、どんどんと見るに耐えないコードになっていってしまったので、挫折。
他の方があげてるコードを見て勉強し、自分なりに解釈して書いたコードが以下。
def is_valid(s) stack = [] s.each_char do |c| # 渡された文字列を一文字ずつ繰り返し case c # cを以下の条件で振り分け when "(", "{", "[" # 開始の括弧なら stack << c # cを配列へ。 #---------------------------------------① when ")" # )なら if stack.pop != "(" # popメソッドで配列の最後を消しつつ、その要素が(じゃなければ return false end #---------------------------------------① #---------------------------------------①と同じ when "}" if stack.pop != "{" return false end #---------------------------------------①と同じ #---------------------------------------①と同じ when "]" if stack.pop != "[" return false end #---------------------------------------①と同じ end end return stack.empty? # 配列は空?→空ならtrue、何かあればfalse(空ということは、開始の括弧と閉じ括弧が同数) end
まっっっったく違います。笑
まずは、最初僕が書いてたコードについて。
僕は何故か、正規表現を使いこなせば、コードを短く済ませる事ができるんじゃないか?と考えてしまいました。(正規表現使いこなせるのカッコイイから憧れてます)
その変なこだわりのせいで、目を酷使して、結果、頭痛くなったんだと思います。笑
正直、他の方のコードを参考にする数回前の失敗時点で、無理じゃね?って思ってたので、その段階で諦めて一旦まっさらの状態からスタートするべきだったかもしれません。
で、別の方のコードを参考にしたコード。
まず、popというメソッド。このコードの存在を知れた事がかなり大きかったです。
配列の最後の要素を消しつつその消した要素を扱えるとは・・・
今までの僕だと、stack[-1]で扱って、その後にdelete_atで消すとかしか発想がなかったので。
ほんと、知識は力だと思いました。
*今回の学び:
- 書いていったコードがダメかもしれないなって思ったら、一旦捨ててみたほうが良いかもしれない。自分の最初の発想に囚われない。
- 理解するためなら、他の方のコードは見た方がいい
- popメソッドは、配列の最後の要素を消す。その際、消した要素を返す。
- each_charでは、文字列を一文字ずつ繰り返し処理。
- caseは、オブジェクトを指定し、後に書くwhenの条件にヒットしていたら、次のwhenかendまでの処理を実行する。
leet code : Longest_Common_Prefix
こんにちは。かずとよです。
本日も、leetcode解いていきます!
早速、問題文の原文が以下。
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string "".
Example 1:
Input: strs = ["flower","flow","flight"] Output: "fl"
Example 2:
Input: strs = ["dog","racecar","car"] Output: "" Explanation: There is no common prefix among the input strings.
Constraints:
0 <= strs.length <= 2000 <= strs[i].length <= 200strs[i]consists of only lower-case English letters.
ここから、解読!
【文字列の配列の中から、最も長い共通のプレフィックスを見つけろ。
共通のプレフィックスがない場合は、空の文字列””を返しましょう。】
今回の問題は、割と翻訳したまんまでした。
でも、プレフィックスというのがよく分からん・・・
とりあえず、例文を見た感じ、共通の文字列を探し出すコードを書けばいいのかな?と。早速やってみました。
↑(これが、後の地獄の始まり)
かなりの試行錯誤の末・・・これで、どうだ!!(ここまでに5回以上の誤回答→熟考→修正を繰り返し、心折れかけ。)
def longest_common_prefix(strs) str_1 = strs[0] # 渡された配列の1つ目 str_2 = strs[1] # 渡された配列の2つ目 str_include = [] # 同じ文字が何文字含まれるかを入れるための配列作っとく if str_2.include?(str_1.slice(0)) # 配列の2つ目に配列の1つ目の1文字目が含まれていれば(例文:2のようなものをはじく) strs.each do |s| # 渡されてる配列を一つずつ繰り返し str_count = 0 str_include_s = 0 while s.to_s.include?(str_1.slice(0..str_count)) # 要素に配列の1つ目の文字(頭〜繰り返し回数)が含まれているなら str_include_s += 1 str_count += 1 if str_count == s.length # 文字数文繰り返したら break # 強制的にループ終了 end end str_include << str_include_s end return str_1.slice(0..str_include.min - 1) else return "" end end
そして・・・
Runtime Error Message:
Line 7: undefined method `slice' for nil:NilClass (NoMethodError) in solution.rb (longest_common_prefix) Line 29 in solution.rb (__driver_helper__) Line 42 in solution.rb (block in _driver) Line 39 in solution.rb (each) Line 39 in solution.rb (each_slice) Line 39 in solution.rb (_driver) Line 54 in solution.rb (<main>)
Last executed input:
おっそろしくエラーでた。
7行目のsliceメソッドがおかしいよ?
なぜ?VSCodeでは問題なく出力できてるのに?
よく分からんけど、とりあえず、それ以外でできる方法考えるか・・・
ってことで、slice使わず、別の方法を試したりとか、めちゃくちゃ色々試しました。(10誤回答ぐらい。)
でも、一生クリアできない。なぜ?
・・・!!!!
Last executed input: ←これ、ちゃんと見てませんでした。激しく後悔。
inputがだったとき、このエラーでたよって言われてたんですね・・・
そりゃ、からっぽの配列の中身を操作できるわけないですよね。
でも、配列が空でも、その配列の中身を添字つけて指定して、変数定義(上のコードで2行目、3行目)は、エラーにならないんやなーと思いました。
まぁ、気持ちを切り替えて!そうと分かれば!
def longest_common_prefix(strs) if strs == [] # 渡された配列が空なら return "" # 空の文字列を返す else str_1 = strs[0] # 渡された配列の1つ目 str_include = [] # 同じ文字が何文字含まれるかを入れるための配列作っとく strs.each do |s| # 渡されてる配列を一つずつ繰り返し str_count = 0 str_include_s = 0 while s.to_s.include?(str_1.slice(0..str_count)) # 要素に配列の1つ目の文字(頭〜繰り返し回数)が含まれているなら str_include_s += 1 str_count += 1 if str_count == s.length # 文字数文繰り返したら break # 強制的にループ終了 end end str_include << str_include_s end include_words = str_1.slice(0..str_include.min - 1) # 全ての要素に含まれる文字を変数定義 if include_words == str_1 # 全ての要素に含まれる文字が配列の1つ目と同じなら return "" # 空の文字列を返す(このコードを入れるまで、配列の要素が全て同じパターンはなかったので) else return include_words end end end
どや!
Status:
Time Limit Exceeded
Last executed input:
[""]
制限時間を超えました、だと?
あぁ、配列空っぽは空の文字列で返すようにしたけど、配列に空の文字列がある場合は指定してなかったな・・・
だから、whileで脱出できず、処理し続けちゃって、ちゃんとできてないんだな。
ここから、めちゃくちゃ試行錯誤。
そして、例文で把握しきれていなかったパターンが様々出てきて、その都度コードを修正しながら正解に近づく・・・
これが、問題文のプレフィックスをちゃんと把握せずに進めた代償です。
僕は、全ての要素に共通して入っている文字だと思って、条件分岐にinclude?を使ってました。
でも、プレフィックスを調べたところ、【頭につく文字列】みたいな事らしく・・・。
発狂。
ここで、1から考え直しです。
大体の型は使いまわせるはずなので、熟考。
include?ではなく、indexを使うことにしました。
そしてまた、トライアンドエラーをひたすら繰り返し・・・
def longest_common_prefix(strs) strs_words = strs.join # 渡された配列をひと繋ぎの文字列にする if strs.include?("") || strs_words.length == 0 # 配列に空の文字列が含まれるか、ひと繋ぎにした文字数が0なら return "" # 空の文字列を返す else str_1 = strs[0] # 渡された配列の1つ目 str_include = [] # 同じ文字が何文字含まれるかを入れるための配列作っとく strs.each do |s| # 渡されてる配列を一つずつ繰り返し str_count = 0 str_include_s = 0 while s.index(str_1.slice(0..str_count)) == 0 # 配列の1つ目の文字(頭〜繰り返し回数)が要素の頭にあるなら str_include_s += 1 str_count += 1 if str_count == s.length # 文字数文繰り返したら break # 強制的にループ終了 end end str_include << str_include_s end include_words = str_1.slice(0..str_include.min - 1) # 全ての要素に含まれる文字を変数定義 if strs.length == 1 # 配列の中の要素が1つなら return include_words # 変数include_wordsを返す else # 配列の中の要素が複数なら if strs.all?{|w| w.index(include_words) == 0} # 配列の全ての要素の頭に変数include_wordsがあるなら return include_words # 変数include_wordsを返す else return "" end end end end
これで、クリアできました。
ここまでで、35回の誤回答を叩き出しました・・・僕はアホかもしれません。
絶対もっといいコードあると思いますが、さすがに力尽きました。
*今回の学び:
- 問題文はしっかり読み、分からないところは事前に調べる
- プレフィックスとは、頭につく文字列のこと
- all?メソッドは、配列の要素を繰り返し実行し、その後に書く{}の条件が全て真の場合にtrueを返すメソッド
- indexメソッドは、文字列の中のどこに、指定の文字列が含まれているか返す
- while文などの無限ループになる可能性があるものの中で、if文などでbleakとすることで、ループを脱出できる。
- joinメソッドは、配列をひと繋ぎの文字列にできる。
オプションがあり、それを使うと区切れたりする?
leetcode : Roman to Integer
こんにちは。かずとよです。
本日も、leetcodeです。
早速問題を。
Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000
For example, 2 is written as II in Roman numeral, just two one's added together. 12 is written as XII, which is simply X + II. The number 27 is written as XXVII, which is XX + V + II.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:
Ican be placed beforeV(5) andX(10) to make 4 and 9.Xcan be placed beforeL(50) andC(100) to make 40 and 90.Ccan be placed beforeD(500) andM(1000) to make 400 and 900.
Given a roman numeral, convert it to an integer.
Example 1:
Input: s = "III" Output: 3
Example 2:
Input: s = "IV" Output: 4
Example 3:
Input: s = "IX" Output: 9
Example 4:
Input: s = "LVIII" Output: 58 Explanation: L = 50, V= 5, III = 3.
Example 5:
Input: s = "MCMXCIV" Output: 1994 Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
Constraints:
1 <= s.length <= 15scontains only the characters('I', 'V', 'X', 'L', 'C', 'D', 'M').- It is guaranteed that
sis a valid roman numeral in the range[1, 3999].
めっちゃ長い。頑張って解読。
【ローマ数字では、I,V,X,L,C,D,Mの7つの異なる記号で数字を表します。I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000
(なんやかんや、この表し方の説明が続くので、省略)
ローマ数字を与えられたら、それを整数に変換してね】
みたいな感じだと思います。
長くなりそうだったので省略してしまいましたが、VI = 6とかIV = 4とかの説明や、それ以外のシンボルでも考え方は同じだよって書いてるみたいです。
まず、このシンボル。見たことあります。ファイナルファンタジーとかで。笑
でも、大体のは50以上になることないので、L以上のシンボルは初見でした。一つ学べました。
あと、このシンボルのIVとかVIの考え方も、今までなんとなくで理解してたところが理由込みで理解できたのでスッキリしました。
さて、色々学べて理解も進んだところで、早速解きます!!
試行錯誤します。かなり試行錯誤しました。
で、回答が以下。
def roman_to_int(s)
s_ary = s.split(//)
# とりあえず渡された値を分割して配列へ
answer = 0
# あとあとの回答のために変数定義
# -----------------------①
s_ary.each_with_index do |s, idx|
# 先ほど作った配列を繰り返し処理(インデックスも)
if idx != 0
# 配列の頭じゃなければ以下を処理
if s == "V" && s_ary[idx - 1] == "I" || s == "X" && s_ary[idx - 1] == "I"
# 要素がVで且つ、一つ前の要素がI。もしくは、要素がXで且つ、一つ前の要素がIなら
s_ary[idx - 1] = "-I"
# 一つ前の要素を-Iと置き換え
elsif s == "L" && s_ary[idx - 1] == "X" || s == "C" && s_ary[idx - 1] == "X"
# 要素がLで且つ、一つ前の要素がX。もしくは、要素がCで且つ、一つ前の要素がXなら
s_ary[idx - 1] = "-X"
# 一つ前の要素を-Xと置き換え
elsif s == "D" && s_ary[idx - 1] == "C" || s == "M" && s_ary[idx - 1] == "C"
# 要素がDで且つ、一つ前の要素がC。もしくは、要素がMで且つ、一つ前の要素がCなら
s_ary[idx - 1] = "-C"
# 一つ前の要素を-Cと置き換え
end
end
end
# -----------------------①
# -----------------------②
s_ary.each do |i|
# 再度、配列の中身を繰り返し
if i == "-I"
# もし要素が-Iなら
answer -= 1
# 答えから-1
elsif i == "-X"
# もし要素が-Xなら
answer -= 10
# 答えから-10
elsif i == "-C"
# もし要素が-Cなら
answer -= 100
# 答えから-100
else
# それ以外(要素が-のないものなら)
i.sub!(/I/, "1")
i.sub!(/V/, "5")
i.sub!(/X/, "10")
i.sub!(/L/, "50")
i.sub!(/C/, "100")
i.sub!(/D/, "500")
i.sub!(/M/, "1000")
# 要素を数字(文字列で)に置き換え
answer += i.to_i
# 答えに先程の要素を数値に変換して足す
end
end
# -----------------------②
return answer
end
一応これでクリアにはなりましたが・・・めちゃ長い。
この回答が、僕の持ってる知識と、調べられる限界でした。
あまりにも長くなったので、自分のために解説しておきます。
とりあえず、渡されたシンボルは一つずつ分割して配列に入れました。
それで、①について。
①では、この配列の中から、4や9、40や90などといった、マイナスの処理をしないといけないものを探し出して、マイナスとわかる形に置き換えました。
これ、最初は2個目のif文だけでやってました。
ただそうすると、頭にVやXなどがあった時、インデックスが-1になってしまって、配列の最後を見てしまい、意図しないところが置き換えられてしまうという事が起きたため、1個目のif文で囲みました。
次に②。②では、①で置き換えた配列の要素たちを合計するだけ。
ただ、配列の中身はまだシンボルのままだし文字列だし、文字列から数値に変換するとマイナスが消えちゃうし・・・っていうことで、if文で分岐させながら、答えとなる変数に足したり引いたりしていきました。
うーん・・・一応クリアできたものの、こんなんでいいのか?
ほんまにむずかしいです。
*今回の学び:
- romanは、浪漫のことじゃない。笑
- V、Xの次にもシンボルがあったという事。実生活では使わないので知らなかった。
- VやXの前にあるIはマイナス。後にあるのはプラス。L、C、D、M等でも同じ考え方。
- splitメソッドで、文字列を分割して配列に格納できる。引数に区切る文字などを入れて使うと、任意の場所で分割できる。今回は、//を引数とし、一文字ずつ分割して使った。
- with_indexめちゃ便利
- subメソッドでは、文字列の中の指定した部分を置き換えできる。
今回は、置き換えた後に使いたかったので、元となるオブジェクト自体を変更できる破壊的メソッドsub!を使いました。
leetcode : Palindrome Number
こんにちは。かずとよです。
今回は、Palindrome Numberという問題を解きました。
問題は以下。
Given an integer x, return true if x is palindrome integer.
An integer is a palindrome when it reads the same backward as forward. For example, 121 is palindrome while 123 is not.
Example 1:
Input: x = 121 Output: true
Example 2:
Input: x = -121 Output: false Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
Example 3:
Input: x = 10 Output: false Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
Example 4:
Input: x = -101 Output: false
Constraints:
-231 <= x <= 231 - 1
翻訳+自分なりの解釈は以下。
【整数xが回文整数なら、true。違うならfalseと返す。
回文整数とは、前からでも後ろからでも同じ数値になる整数のこと。
121は回文整数で、123はそうではない。】
さらに例文2の文章
【このパターンは、前から読むと-121。後ろから読むと121-となる。
よって、回文整数ではない。】
ふむ・・・なるほど。
ということは、負の数は全て回文整数ではないということ。
ならば、これでどうじゃい!!
def is_palindrome(x)
if x >= 0
# xが0以上なら(正の数、もしくは0)
x_reverse_s = x.to_s.reverse
# 一旦xを文字列にして、反転。
x_reverse = x_reverse_s.to_i
# 数値に変換
if x == x_reverse
# ここで再度条件分岐。xと反転したもの(x_reverse)が同じなら
return true
else
return false
end
else
# そもそも負の数なら
return false
end
end
クリアできました。
今回は、意外とあっさりいけました。
知ってることだけで解けたので、web検索もなしでした。翻訳以外。
(そもそもfalseと返す記述をしてなかったり、0をfalseで返してしまったりといったミスはありましたが)
*今回の学び:
- 回文整数とは、前から読んでも後ろから読んでも同じ数字になるもの。負の数は-がある時点で回文整数になり得ない。
- 0も回文整数である。
leetcode : reverse integer
こんにちは。かずとよです。
今回は、reverse integerという問題のアウトプットです。
例の如く、英語の問題文が以下。
Given a signed 32-bit integer x, return x with its digits reversed. If reversing x causes the value to go outside the signed 32-bit integer range [-231, 231 - 1], then return 0.
Assume the environment does not allow you to store 64-bit integers (signed or unsigned).
Example 1:
Input: x = 123 Output: 321
Example 2:
Input: x = -123 Output: -321
Example 3:
Input: x = 120 Output: 21
Example 4:
Input: x = 0 Output: 0
Constraints:
-231 <= x <= 231 - 1
もちろん分からないので、翻訳しつつ解釈。
【xに渡した数字を反転させる。123なら、321というように。
ただし、xが32ビット整数の範囲を超えていた場合、0と出力させる。】
こんな感じだと思います。
・・・32ビット整数?なんじゃそりゃ?
まぁ、よくわからんけどとりあえずやってみよう。
以下、とりあえず試行錯誤した結果
# @param {Integer} x
# @return {Integer}
def reverse(x)
if x >= 1
# xが1以上なら(正の数なら)
x_s = x.to_s.reverse
# 一旦ひっくり返せる様に文字列に変換して、reverse
return x_s.to_i
# 数値に戻して返す
elsif x <= -1
# xが-1以下なら(負の数なら)
x_s = x.to_s.reverse
# ここは正の数字と同じ
answer = (x_s.to_i) - (x_s.to_i * 2)
# 上の反転処理の時に-が消えてしまったので、再度負の数にして、変数に代入
return answer
else
# 残るは0だけなので
return 0
end
end
しかし、これでは不正解でした。
どうも、0を求めてるらしい。反転できてるのに・・・なんでだ?
考えてると、頭の隅っこで32ビット整数が存在をアピールしてきました。
やっぱり、32ビット整数をしっかり考えないといけないのかな・・・
ということで、調べました。
【32ビットに格納できる符号なし整数の範囲は、0 から 4,294,967,295 である。
符号付き整数は −2,147,483,648 から 2,147,483,647 を格納できる。】
とのことでした。
今回の例文をみていると、例文2に-123は-321とあります。
なので、今回意識しないといけないのは、さっき調べたものの符号付き整数の方。
確かに、不正解の時のoutputをみると、2,147,483,647を超えています。
なるほど、そうなるときは、0と返さないといけないのか・・・
そして、再度試行錯誤の末・・・
# @param {Integer} x
# @return {Integer}
def reverse(x)
if x >= 1
# xが1以上なら(正の数なら)
x_s = x.to_s.reverse
# 一旦ひっくり返せる様に文字列に変換して、reverse
x_plus = x_s.to_i
# 数値に戻す
if x_plus >= 2147483648
# ここで再度条件分岐。さっき定義した変数が32ビット整数以上なら
return 0
else
return x_plus
end
elsif x <= -1
# xが-1以下なら(負の数なら)
x_s = x.to_s.reverse
# ここは正の数字と同じ
x_minus = (x_s.to_i) - (x_s.to_i * 2)
# 上の反転処理の時に-が消えてしまったので、再度負の数に。
if x_minus <= -2147483648
# x_minusが32ビット整数の範囲を超えていたらという条件で。
return 0
else
return x_minus
end
else
# 残るは0だけなので
return 0
end
end
これで、なんとかクリアでした。
いやいや、マジで難しすぎるよ、これ。
現役エンジニアの方々は、こんなの余裕で解けるの?やばくね?って感じました。
*今回の学び:
- .reverseで【文字列】を反転させる事ができる。(数値は不可)
- 文字列へ変換すると、-は消え去る
- 32ビット整数とは、32ビットに格納できる整数の範囲のこと。
そもそも、2進数で表現されるので、32ビットに格納できる整数の範囲は、0〜2の32乗-1となる。
16ビットは16乗、8ビットは8乗という様な感じらしい。 - よって、32ビット整数とは、符号なしの場合、0から4,294,967,295。
符号付き整数は、 −2,147,483,648 から 2,147,483,647。
leetcodeを始めました。
スキルテストで、leetcodeから出題されることがわかった為、登録をして初めてみました。
SNSサインアップができたので、とりあえず済ませ、早速・・・
全部、英語。
英語です。正直全然わからないものの、なんとか問題ページに辿り着き、とりあえず一問解いてみようと、難易度easyのtwo sumという問題を選択。
そして問題文が以下。
Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
Example 1:
Input: nums = [2,7,11,15], target = 9 Output: [0,1] Output: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6 Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6 Output: [0,1]
Constraints:
2 <= nums.length <= 103-109 <= nums[i] <= 109-109 <= target <= 109- Only one valid answer exists.
うん、わからん。
翻訳サイトを駆使して、問題文を読み解きます。
・・・おそらくですが。
【仮引数numsには数値がいくつか入った配列を、targetには数値ひとつを、実引数として渡します。
numsの中のどことどこの数値を足せばtargetになるかを出力させる。
当てはまるのは1パターンですよ。】
的な意味かな?おそらく。
早速、試行錯誤しながら解いてみて、導き出せた僕の回答は以下。(1時間ぐらいかかった・・・)
# @param {Integer[]} nums
# @param {Integer} target
# @return {Integer[]}
def two_sum(nums, target)
nums.each_with_index do |i, idx|
# 配列numsを繰り返し処理。オプションでインデックスも取得する
x = target - i
# 変数xにtargetからiを引いて、あと数字がいくつ残るかを代入
if nums.include?(x) && nums.index(x) != idx
# 配列内にxがあって、且つ、xがidxと同じでないならば
y = nums.index(i)
z = nums.rindex(x)
return [y, z]
end
end
end
これで一応クリアできた・・・
めちゃくちゃ難しかったです。
*今回の学び:
- each_with_indexを使うと、繰り返し処理の際にその処理をしている要素の順番も取得できる。
- 配列.index(要素)で、その要素の場所を頭から探し、最初に当てはまった場所の順番を取得できる
- 配列.rindex(要素)は、上記の逆から探してくれる版。
- 2つの数字の和を探すときは、差を見ればすぐに探し出せる。