diff --git a/238_ProductofArrayExceptSelf/main/Makefile b/238_ProductofArrayExceptSelf/main/Makefile new file mode 100644 index 0000000..88b6f73 --- /dev/null +++ b/238_ProductofArrayExceptSelf/main/Makefile @@ -0,0 +1,30 @@ +# コンパイラの設定 +CXX = g++ +# コンパイルオプション +CXXFLAGS = -std=c++17 -Wall -Wextra -O2 -I/Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk/usr/include/c++/v1/ + +# 実行ファイル名 +TARGET = main +SRC = main.cpp +HDR = main.h + +# オブジェクトファイル(.o)の名前 +OBJ = $(SRC:.cc=.o) + +# デフォルトターゲット:実行ファイルを作成 +all: $(TARGET) + +# 実行ファイルを作成するルール +$(TARGET): $(OBJ) + # オブジェクトファイルから実行ファイルを作成 + $(CXX) $(CXXFLAGS) -o $@ $^ + +# .cc から .o を作成するルール +%.o: %.cc $(HDR) + # ソースコードをコンパイルしてオブジェクトファイルを生成 + $(CXX) $(CXXFLAGS) -c $< -o $@ + +# クリーンアップターゲット:コンパイル生成物を削除 +clean: + # コンパイルで生成されたオブジェクトファイルと実行ファイルを削除 + rm -f $(OBJ) $(TARGET) diff --git a/238_ProductofArrayExceptSelf/main/main b/238_ProductofArrayExceptSelf/main/main new file mode 100755 index 0000000..9184614 Binary files /dev/null and b/238_ProductofArrayExceptSelf/main/main differ diff --git a/238_ProductofArrayExceptSelf/main/main.cpp b/238_ProductofArrayExceptSelf/main/main.cpp new file mode 100644 index 0000000..4cc2a3c --- /dev/null +++ b/238_ProductofArrayExceptSelf/main/main.cpp @@ -0,0 +1,35 @@ +#include "main.h" +#include + +// Solution::をつけないとグローバル関数となる +std::vector Solution::productExceptSelf(std::vector& nums) { + if (nums.size() == 0) { + return {}; + } + std::vector products_except_self(nums.size(), 1); + int prefix_product = 1; + for (int i = 0; i < nums.size(); i++) { + products_except_self[i] *= prefix_product; + prefix_product *= nums[i]; + } + + int suffix_product = 1; + for (int i = nums.size() - 1; i >= 0; i--) { + products_except_self[i] *= suffix_product; + suffix_product *= nums[i]; + } + + return products_except_self; +} + +int main() { + Solution solution; + std::vector nums = {-1,1,0,-3,3}; + std::vector products = solution.productExceptSelf(nums); + std::cout << "Output is: "; + for (int product : products) { + std::cout << product << " "; + } + std::cout << std::endl; + return 0; +} diff --git a/238_ProductofArrayExceptSelf/main/main.h b/238_ProductofArrayExceptSelf/main/main.h new file mode 100644 index 0000000..262c717 --- /dev/null +++ b/238_ProductofArrayExceptSelf/main/main.h @@ -0,0 +1,11 @@ +#ifndef PRODUCT_EXCEPT_SELF_MAIN_MAIN_H_ // The format of the symbol name should be ___H_. +#define PRODUCT_EXCEPT_SELF_MAIN_MAIN_H_ + +#include + +class Solution { + public: + std::vector productExceptSelf(std::vector& nums); +}; + +#endif diff --git a/238_ProductofArrayExceptSelf/memo.md b/238_ProductofArrayExceptSelf/memo.md new file mode 100644 index 0000000..f09b719 --- /dev/null +++ b/238_ProductofArrayExceptSelf/memo.md @@ -0,0 +1,57 @@ +## ステップ1 +O(n)で実装する必要があるためvectorを2回見ていく方法は使えない +全てを掛け合わせた数字を出してから、nums[i]を割っていいく方法が思いついたが +割り算も制約上使えない + +問題をもう一度読み直す +>The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer. +わざわざprefixとsuffixが記載があるということをヒントに +iの位置までの合計とiより後ろの合計を管理するvectorを二つ用意して + +最終的に掛け合わせると回答できそう +時間計算量O(n) +空間計算量O(n) + +acceptまで30分 + +## ステップ2 +nums[i]を掛ける順序とタイミングを考えれば、 +iの位置までの合計とiより後ろの合計を管理するvectorを使う必要がなくなる。 + +prefix_productとsuffix_productを使ってそれぞれ左側と右側の積を保持する。 +products_except_self[i]に掛けた後に、 +prefix_productとsuffix_productをnums[i]で更新することで、 +各ステップではnums[i]を除いた積だけが使われるようになっている +=>いきなりこの解法に辿り着くのは難しそう + +vectorの初期化について +https://stackoverflow.com/questions/42743604/default-values-when-creating-a-vector-c +いつも忘れるので気になったら都度読む癖をつける + +## ステップ3 +**3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。** + +## 他の方の解法 +prefixやsuffixを単体で使うよりprefix_〇〇というように何が入っているのかわかるような名前がいいと感じた +resやlengthに関しても何が入っているのか分かるような変数名をつけたい +https://github.com/t-ooka/leetcode/pull/5 + +indexの管理方法を考えることで左側の積と右側の積を一度に計算することができる +https://discord.com/channels/1084280443945353267/1200089668901937312/1200403156073455646 +## Discorなど + +# PRに対するコメント +partial_sumとtransformを使っても解答可能 +=>いずれの関数も知らなかったので普段使っている物以外にも足を伸ばす姿勢を意識。 + +partial_sum +https://cpprefjp.github.io/reference/numeric/partial_sum.html +https://en.cppreference.com/w/cpp/algorithm/partial_sum + +multiplies +https://cpprefjp.github.io/reference/functional/multiplies.html +https://en.cppreference.com/w/cpp/utility/functional/multiplies + +transform +https://cpprefjp.github.io/reference/algorithm/transform.html +https://en.cppreference.com/w/cpp/algorithm/transform diff --git a/238_ProductofArrayExceptSelf/step1.cpp b/238_ProductofArrayExceptSelf/step1.cpp new file mode 100644 index 0000000..17521c1 --- /dev/null +++ b/238_ProductofArrayExceptSelf/step1.cpp @@ -0,0 +1,27 @@ +class Solution { + public: + vector productExceptSelf(vector& nums) { + if (nums.size() == 0) { + return {}; + } + vector prefix_products(nums.size()); + // デフォルトの初期化は0だが、 + // indexが0の場所の計算に影響を与えないように1で初期化する + prefix_products[0] = 1; + for (int i = 1; i < nums.size(); i++) { + prefix_products[i] = prefix_products[i - 1] * nums[i - 1]; + } + + vector suffix_products(nums.size()); + suffix_products[nums.size() - 1] = 1; + for (int i = nums.size() - 2; i >= 0; i--) { + suffix_products[i] = suffix_products[i + 1] * nums[i + 1]; + } + + vector products_except_self(nums.size()); + for (int i = 0; i < nums.size(); i++) { + products_except_self[i] = prefix_products[i] * suffix_products[i]; + } + return products_except_self; + } + }; diff --git a/238_ProductofArrayExceptSelf/step2.cpp b/238_ProductofArrayExceptSelf/step2.cpp new file mode 100644 index 0000000..64c699e --- /dev/null +++ b/238_ProductofArrayExceptSelf/step2.cpp @@ -0,0 +1,24 @@ +class Solution { + public: + vector productExceptSelf(vector& nums) { + if (nums.size() == 0) { + return {}; + } + + // デフォルトは0で初期化されるので1で初期化しておく + vector products_except_self(nums.size(), 1); + int prefix_product = 1; + for (int i = 0; i < nums.size(); i++) { + products_except_self[i] *= prefix_product; + prefix_product *= nums[i]; + } + + int suffix_product = 1; + for (int i = nums.size() - 1; i >= 0; i--) { + products_except_self[i] *= suffix_product; + suffix_product *= nums[i]; + } + + return products_except_self; + } + }; diff --git a/238_ProductofArrayExceptSelf/step3.cpp b/238_ProductofArrayExceptSelf/step3.cpp new file mode 100644 index 0000000..eea9bc6 --- /dev/null +++ b/238_ProductofArrayExceptSelf/step3.cpp @@ -0,0 +1,23 @@ +class Solution { + public: + vector productExceptSelf(vector& nums) { + if (nums.size() == 0) { + return {}; + } + + vector products_except_self(nums.size(), 1); + int prefix_product = 1; + for (int i = 0; i < nums.size(); i++) { + products_except_self[i] *= prefix_product; + prefix_product *= nums[i]; + } + + int suffix_product = 1; + for (int i = nums.size() - 1; i >= 0; i--) { + products_except_self[i] *= suffix_product; + suffix_product *= nums[i]; + } + + return products_except_self; + } + }; diff --git a/238_ProductofArrayExceptSelf/step4_1.cpp b/238_ProductofArrayExceptSelf/step4_1.cpp new file mode 100644 index 0000000..b930b2e --- /dev/null +++ b/238_ProductofArrayExceptSelf/step4_1.cpp @@ -0,0 +1,21 @@ +class Solution { + public: + vector productExceptSelf(vector& nums) { + if (nums.empty()) { + return {}; + } + + int num_size = nums.size(); + + vector prefix_products(num_size, 1); + partial_sum(nums.begin(), nums.end() - 1, prefix_products.begin() + 1, multiplies()); + + vector suffix_products(num_size, 1); + partial_sum(nums.rbegin(), nums.rend() - 1, suffix_products.rbegin() + 1, multiplies()); + + vector products_except_self(num_size); + transform(prefix_products.begin(), prefix_products.end(), suffix_products.begin(), + products_except_self.begin(), multiplies()); + return products_except_self; + } + }; diff --git a/238_ProductofArrayExceptSelf/step4_2.cpp b/238_ProductofArrayExceptSelf/step4_2.cpp new file mode 100644 index 0000000..b226930 --- /dev/null +++ b/238_ProductofArrayExceptSelf/step4_2.cpp @@ -0,0 +1,23 @@ +class Solution { + public: + vector productExceptSelf(vector& nums) { + if (nums.empty()) { + return {}; + } + + vector products_except_self(nums.size(), 1); + int prefix_product = 1; + for (int i = 0; i < nums.size(); i++) { + products_except_self[i] *= prefix_product; + prefix_product *= nums[i]; + } + + int suffix_product = 1; + for (int i = nums.size() - 1; i >= 0; i--) { + products_except_self[i] *= suffix_product; + suffix_product *= nums[i]; + } + + return products_except_self; + } + };