diff --git a/287_find_the_duplicate_number/a.out b/287_find_the_duplicate_number/a.out new file mode 100755 index 0000000..4f779b7 Binary files /dev/null and b/287_find_the_duplicate_number/a.out differ diff --git a/287_find_the_duplicate_number/image.png b/287_find_the_duplicate_number/image.png new file mode 100644 index 0000000..995cb77 Binary files /dev/null and b/287_find_the_duplicate_number/image.png differ diff --git a/287_find_the_duplicate_number/memo.md b/287_find_the_duplicate_number/memo.md new file mode 100644 index 0000000..36bc580 --- /dev/null +++ b/287_find_the_duplicate_number/memo.md @@ -0,0 +1,163 @@ +# 287. find-the-duplicate-number + +https://leetcode.com/problems/find-the-duplicate-number/description/ + +## Comments +09:32 +空間計算量がO(1)であることがめっちゃだるそう。配列の値をそのまま使う。。。? +2分探索ならうまくいくのかなぁ。 +時間計算量はO(nlogn)になって実行可能ではありそう。 +空間計算量はO(1)になる。 + +具体的な二分探索方法 +1-n/2の数が、n/2 + 1個あるなら、前半側の数字に重複がある。 +逆もしかり。 + +1 - n/4の数が、n/4 + 1個あるなら、前半側の数字に重複がある。 +を繰り返す。 + +のかなぁ。 +再帰でやる?itereationでやる? +iterationでやると、while文の中で配列の値を使うことになるので、ちょっとだるい。 +再帰でやるなら、回数を継続していきたい。どうやって引数に渡すのか。 +whileで回すほうが楽か。 + +### step1 +```c +// 1. 配列の値をそのまま使う +int findDuplicate(int* nums, int numsSize) +{ + int i; + int first; + + i = 0; + first = 0; + while (i < numsSize) + { + if (nums[i] < numsSize / 2) + first++; + else + first--; + i++; + } + if (first > 0) + { + // 前半側に重複がある + return findDuplicate(nums, numsSize / 2); + } + else + { + // 後半側に重複がある + return findDuplicate(nums + numsSize / 2, numsSize - numsSize / 2); + } +} +``` +* +うーんnumSizeは固定にしたい。。。 +Static変数にして、再帰のたびにnumsSizeを渡すのはどうだろう。 + +### step2 +```c +// 1. 配列の値をそのまま使う +int findDuplicate(int* nums, int numsSize) +{ + int i; + int first; + static int numSize_copy = numsSize; + + i = 0; + first = 0; + while (i < numsSize_copy) + { + if (nums[i] < numsSize / 2) + first++; + else + first--; + i++; + } + if (first > 0) + { + // 前半側に重複がある + return findDuplicate(nums, numsSize / 2); + } + else + { + // 後半側に重複がある + return findDuplicate(nums + numsSize / 2, numsSize - numsSize / 2); + } +} +``` +* +いけんちゃうかなぁ。main関数を作成して、テストしてみよう。 + +```c +#include + +int main(void) +{ + int nums[] = {1, 2, 3, 3}; + int numsSize = 4; + + printf("%d\n", findDuplicate(nums, numsSize)); + return (0); +} +``` +うごかんなぁ。 +セグフォがでる。 +static変数を仮引数で初期化するのはだめらしい。 +なんでなんやろう。 +一旦固定値でやろう。 +やったけど無理そう。セグフォがでる。 +indexとかめんどくさいなぁ。やっぱwhileでやるほうが楽そう。 +while文に変更しよう。 +### step3 +```c + +int findDuplicate(int *nums, int numsSize) +{ + int left; + int mid; + int right; + int i; + int count; + + left = 0; + right = numsSize - 1; + while (left < right) + { + mid = (left + right) / 2; + count = 0; + i = 0; + while (i < numsSize) + { + if (nums[i] <= mid) + count++; + i++; + } + if (count > mid) + right = mid; + else + left = mid + 1; + } + return (left); +} + +#include + +int main(void) +{ + int nums[] = {1, 2, 4, 5, 3, 2}; + int numsSize = 6; + + printf("%d\n", findDuplicate(nums, numsSize)); + return (0); +} + +``` +めっちゃきれいに実装できた。 +mainのテスト何個か試しても行けた +行けてそう!! +![result](image.png) +いけた!! +なんかめちゃ早の人たちいる。 +何なんやろ。 diff --git a/287_find_the_duplicate_number/step1.c b/287_find_the_duplicate_number/step1.c new file mode 100644 index 0000000..187d7e3 --- /dev/null +++ b/287_find_the_duplicate_number/step1.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* step1.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kjikuhar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/06/02 09:47:39 by kjikuhar #+# #+# */ +/* Updated: 2025/06/02 09:55:16 by kjikuhar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +// 1. 配列の値をそのまま使う +int findDuplicate(int* nums, int numsSize) +{ + int i; + int first; + static int numsSize_copy = 4; + + i = 0; + first = 0; + while (i < numsSize_copy) + { + if (nums[i] < numsSize / 2) + first++; + else + first--; + i++; + } + if (first > 0) + { + // 前半側に重複がある + return findDuplicate(nums, numsSize / 2); + } + else + { + // 後半側に重複がある + return findDuplicate(nums, numsSize - numsSize / 2); + } +} + +#include + +int main(void) +{ + int nums[] = {1, 2, 3, 3}; + int numsSize = 4; + + printf("%d\n", findDuplicate(nums, numsSize)); + return (0); +} diff --git a/287_find_the_duplicate_number/step2.c b/287_find_the_duplicate_number/step2.c new file mode 100644 index 0000000..2291272 --- /dev/null +++ b/287_find_the_duplicate_number/step2.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* step2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kjikuhar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/06/02 09:47:39 by kjikuhar #+# #+# */ +/* Updated: 2025/06/02 14:19:49 by kjikuhar ### ########.fr */ +/* */ +/* ************************************************************************** */ + + +int findDuplicate(int *nums, int numsSize) +{ + int left; + int mid; + int right; + int i; + int count; + + left = 0; + right = numsSize - 1; + while (left < right) + { + mid = (left + right) / 2; + count = 0; + i = 0; + while (i < numsSize) + { + if (nums[i] <= mid) + count++; + i++; + } + if (count > mid) + right = mid; + else + left = mid + 1; + } + return (left); +} + +#include + +int main(void) +{ + int nums[] = {1, 2, 4, 5, 3, 2}; + int numsSize = 6; + + printf("%d\n", findDuplicate(nums, numsSize)); + return (0); +} diff --git a/287_find_the_duplicate_number/step3.c b/287_find_the_duplicate_number/step3.c new file mode 100644 index 0000000..4afef40 --- /dev/null +++ b/287_find_the_duplicate_number/step3.c @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* step3.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kjikuhar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/06/02 15:04:50 by kjikuhar #+# #+# */ +/* Updated: 2025/06/02 15:16:38 by kjikuhar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +// Floyd's Toroise & Hare algorithm +// Cycle detection + +int findDuplicate(int* nums, int n) +{ + int tortoize; + int hare; + + tortoize = 0; + hare = 0; + while (1) + { + tortoize = nums[tortoize]; + hare = nums[nums[hare]]; + if (tortoize == hare) + break ; + } + tortoize = 0; + while (1) + { + tortoize = nums[tortoize]; + hare = nums[hare]; + if (tortoize == hare) + break ; + } + return (hare); +} + + +#include + +int main(void) +{ + int nums[] = {3, 1, 3, 4, 2}; + int numsSize = 5; + + printf("%d\n", findDuplicate(nums, numsSize)); + return (0); +} diff --git a/create.sh b/create.sh old mode 100644 new mode 100755 index 1efeebc..fc4c191 --- a/create.sh +++ b/create.sh @@ -42,9 +42,9 @@ git checkout -b "$DIR_NAME" mkdir -p "$DIR_NAME" # Create empty files under the directory -touch "$DIR_NAME/step1.py" -touch "$DIR_NAME/step2.py" -touch "$DIR_NAME/step3.py" +touch "$DIR_NAME/step1.c" +touch "$DIR_NAME/step2.c" +touch "$DIR_NAME/step3.c" touch "$DIR_NAME/memo.md" # Populate memo.md using a heredoc @@ -57,15 +57,15 @@ $URL ### step1 -* +* ### step2 -* +* ### step3 -* +* EOF echo "Directory '$DIR_NAME' created with template files: step1.py, step2.py, step3.py, memo.md" diff --git a/prcreate.sh b/prcreate.sh old mode 100644 new mode 100755