-
Notifications
You must be signed in to change notification settings - Fork 0
191. Number of 1 Bits #76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
|
Comment on lines
+46
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 考え方は他の解法にも似ているのですが、全てのbitをチェックする代わりに、最も右にあるbitを消すことで処理するアルゴリズムもあるようです。 int hammingWeight(unsigned int n) {
int count = 0;
while (n) {
n &= (n - 1);
count++;
}
return count;
}
|
||
|
|
||
| ## Discordなど | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,13 @@ | ||||||||||||||
| class Solution { | ||||||||||||||
| public: | ||||||||||||||
| int hammingWeight(int n) { | ||||||||||||||
| int num_bits = 0; | ||||||||||||||
| while (n > 0) { | ||||||||||||||
| if (n % 2 == 1) { | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. num_bits += n % 2;とも書けます。趣味の範囲だと思います。 |
||||||||||||||
| num_bits +=1; | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||
| } | ||||||||||||||
| n /= 2; | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 個人的には n >>= 1;と書きます。コンパイラーで最適化オプションを付けてコンパイルすると、どちらもシフト演算の命令が生成されると思います。ぜひ確かめてみてください。 整数の割り算は遅い、ビット演算は速い、という感覚は持っておいたほうが良いと思います。以下 Ice Lake and Tiger Lake
https://zenn.dev/herumi/articles/latency-throughput
|
||||||||||||||
| } | ||||||||||||||
| return num_bits; | ||||||||||||||
| } | ||||||||||||||
| }; | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 自分なら mask 変数は使わず、 if ((n & (1 << i)) != 0) {と書くと思います。趣味の範囲だと思います。 |
||
| num_bits++; | ||
| } | ||
| mask <<= 1; | ||
| } | ||
| return num_bits; | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| class Solution { | ||
| public: | ||
| int hammingWeight(int n) { | ||
| return GenerichammingWeight(n); | ||
| } | ||
|
|
||
| private: | ||
| template <typename T> | ||
| std::enable_if_t<std::is_integral_v<T>, int> GenerichammingWeight(T n) { | ||
| int num_bits = 0; | ||
| T mask = 1; | ||
| constexpr int num_digits = std::numeric_limits<T>::digits; | ||
|
|
||
| for (int i = 0; i < num_digits; ++i) { | ||
| if ((n & mask) != 0) { | ||
| num_bits++; | ||
| } | ||
| mask <<= 1; | ||
| } | ||
|
|
||
| return num_bits; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } | ||
| }; |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
分割統治法による解法もあります。
「ハッカーのたのしみ: 本物のプログラマはいかにして問題を解くか」に載っています。ソフトウェアエンジニアの常識には含まれていませんが、知っている人はいると思います。