From 1b15cae4b78b1463fcf0f92158a6dd79ec6c91f1 Mon Sep 17 00:00:00 2001 From: Ryotaro Kurita Date: Fri, 8 Aug 2025 00:02:18 +0900 Subject: [PATCH] finish --- 191.Numberof1Bits/bit_manipulation.cpp | 13 ++++++ 191.Numberof1Bits/memo.md | 57 ++++++++++++++++++++++++++ 191.Numberof1Bits/step1.cpp | 13 ++++++ 191.Numberof1Bits/step2.cpp | 14 +++++++ 191.Numberof1Bits/step2_2.cpp | 23 +++++++++++ 191.Numberof1Bits/step3.cpp | 14 +++++++ 6 files changed, 134 insertions(+) create mode 100644 191.Numberof1Bits/bit_manipulation.cpp create mode 100644 191.Numberof1Bits/memo.md create mode 100644 191.Numberof1Bits/step1.cpp create mode 100644 191.Numberof1Bits/step2.cpp create mode 100644 191.Numberof1Bits/step2_2.cpp create mode 100644 191.Numberof1Bits/step3.cpp diff --git a/191.Numberof1Bits/bit_manipulation.cpp b/191.Numberof1Bits/bit_manipulation.cpp new file mode 100644 index 0000000..a2276a5 --- /dev/null +++ b/191.Numberof1Bits/bit_manipulation.cpp @@ -0,0 +1,13 @@ +class Solution { +public: + int hammingWeight(int n) { + int num_bits = 0; + while (n != 0) { + num_bits += 1; + // nと(n-1)のビットごとのAND演算を行うことで、 + // nの最も右側にある1のビットを0に反転させる + n &= (n - 1); + } + return num_bits; + } +}; diff --git a/191.Numberof1Bits/memo.md b/191.Numberof1Bits/memo.md new file mode 100644 index 0000000..7151063 --- /dev/null +++ b/191.Numberof1Bits/memo.md @@ -0,0 +1,57 @@ +## ステップ1 +思いついた方法は、与えられた数字を2で割りつど余りがでたらbitのカウントを増やす方法 +他の解法は思いつかずacceptまで2分 +時間計算量はO(log n) +空間計算量はO(1) + +15分ほど考えたが他の方法は思いつかなかった + +## ステップ2 +想定されている解法は愚直にbitが立っている場合を見る方法かbit manipulationか +愚直にbitが立っている場合を見る方法をstep2とstep3を進める + +これは1ビットずつ確認する方法 + +例えば5(0101)の場合で考えると +マスクは0001 0010 0100 1000と動く(実際は32bit分) +マスクを動かしながらビットが立っている部分を数える + +n & maskが返却しているものはbitが1である場合の2^1 +=>これを理解するのに時間がかかった + +int型しか対応できなさそうなのが気になった +=>step2_2.cppに実装 +関数の型定義のテンプレート化部分は、分からなかったのでChatGptに聞いた + +## ステップ3 +**3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。** + +## 他の解法 + + +他にはbit manipulationがあるbit_manipulation.cppに実装 +解説を読んだが理解できていない気がする。 + +nの最も右側にある1を0に更新し、これを全て0になるまで続ける +n = 12の場合 +n : 00001100 +n - 1: 00001011 +andをとると8: 00001000となる + +n : 00001000 +n - 1: 00000111 +andをとると0: 00000000となる +この場合2ループで、1の数は2 + +コードが見れなくなっていたのでやり取りだけチェック +この辺りチェックしたら良さそう +https://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation +C++のもありそうなので探してみる +https://pkg.go.dev/math/bits#OnesCount +https://github.com/rihib/leetcode/pull/46 + +文字列に変換する方法などもある +https://github.com/Kitaken0107/GrindEasy/pull/24 + +## Discordなど + diff --git a/191.Numberof1Bits/step1.cpp b/191.Numberof1Bits/step1.cpp new file mode 100644 index 0000000..ea9dc05 --- /dev/null +++ b/191.Numberof1Bits/step1.cpp @@ -0,0 +1,13 @@ +class Solution { +public: + int hammingWeight(int n) { + int num_bits = 0; + while (n > 0) { + if (n % 2 == 1) { + num_bits +=1; + } + n /= 2; + } + return num_bits; + } +}; diff --git a/191.Numberof1Bits/step2.cpp b/191.Numberof1Bits/step2.cpp new file mode 100644 index 0000000..5c8658e --- /dev/null +++ b/191.Numberof1Bits/step2.cpp @@ -0,0 +1,14 @@ +class Solution { +public: + int hammingWeight(int n) { + int num_bits = 0; + int mask = 1; + for (int i = 0; i < 32; i++) { + if ((n & mask) != 0) { + num_bits++; + } + mask <<= 1; + } + return num_bits; + } +}; diff --git a/191.Numberof1Bits/step2_2.cpp b/191.Numberof1Bits/step2_2.cpp new file mode 100644 index 0000000..28e0e6a --- /dev/null +++ b/191.Numberof1Bits/step2_2.cpp @@ -0,0 +1,23 @@ +class Solution { +public: + int hammingWeight(int n) { + return GenerichammingWeight(n); + } + +private: + template + std::enable_if_t, int> GenerichammingWeight(T n) { + int num_bits = 0; + T mask = 1; + constexpr int num_digits = std::numeric_limits::digits; + + for (int i = 0; i < num_digits; ++i) { + if ((n & mask) != 0) { + num_bits++; + } + mask <<= 1; + } + + return num_bits; + } +}; diff --git a/191.Numberof1Bits/step3.cpp b/191.Numberof1Bits/step3.cpp new file mode 100644 index 0000000..5c8658e --- /dev/null +++ b/191.Numberof1Bits/step3.cpp @@ -0,0 +1,14 @@ +class Solution { +public: + int hammingWeight(int n) { + int num_bits = 0; + int mask = 1; + for (int i = 0; i < 32; i++) { + if ((n & mask) != 0) { + num_bits++; + } + mask <<= 1; + } + return num_bits; + } +};