From 4da34a657dadb15a7047c7f235555ed4558ccc01 Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:32:49 +0900 Subject: [PATCH 01/10] add 1.cpp --- .../1.cpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 01-15/4.First Unique Character in a String/1.cpp diff --git a/01-15/4.First Unique Character in a String/1.cpp b/01-15/4.First Unique Character in a String/1.cpp new file mode 100644 index 0000000..dd5d089 --- /dev/null +++ b/01-15/4.First Unique Character in a String/1.cpp @@ -0,0 +1,43 @@ +#if __has_include("../debug.hpp") +#include "../debug.hpp" +#endif +// ここまでローカルでのデバッグ用なので気にしないでください -------------------- + +#include + +using namespace std; + +// <時間> +// 18分 +// <感想> +// 一周回って変なことしてしまったと思う +// 原因があるとすれば、O(2N)=O(N)を体で理解していないこと? +// それでも実行時間は早いかなと思ったら全然早くなかった +// 可能性があるとすればO(N)かかる方のif文の分岐かな +// 反省のために残しておく + +// なお以下で出てくるコメントはプロダクト版にも書くつもりのコメント +class Solution { + public: + int firstUniqChar(string s) { + vector indexes(26, -1); + vector is_repeated(26); + for (int i = 0; i < s.size(); ++i) { + auto alpha = s[i] - 'a'; + if (indexes[alpha] == -1) { + indexes[alpha] = i; + } else { + is_repeated[alpha] = true; + } + } + + int min_index = s.size(); + for (int alpha = 0; alpha < 26; ++alpha) { + if (indexes[alpha] != -1 && !is_repeated[alpha]) { + min_index = min(min_index, indexes[alpha]); + } + } + + return min_index != s.size() ? min_index : -1; + } +}; From c6c62e3d50539ad053ca7ae8c408c33871b7bda9 Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:32:53 +0900 Subject: [PATCH 02/10] add 2.cpp --- .../2.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 01-15/4.First Unique Character in a String/2.cpp diff --git a/01-15/4.First Unique Character in a String/2.cpp b/01-15/4.First Unique Character in a String/2.cpp new file mode 100644 index 0000000..36807d2 --- /dev/null +++ b/01-15/4.First Unique Character in a String/2.cpp @@ -0,0 +1,29 @@ +#if __has_include("../debug.hpp") +#include "../debug.hpp" +#endif +// ここまでローカルでのデバッグ用なので気にしないでください -------------------- + +#include + +using namespace std; + +// <時間> +// 1分 +// <疑問・不安点(・個人的な感想、違う意見があれば教えてほしいもの)> +// - s[i] - 'a'が初見で伝わるのか問題 +// - countsの他の命名候補としてalpha_countsがあった + +// なお以下で出てくるコメントはプロダクト版にも書くつもりのコメント +class Solution { + public: + int firstUniqChar(string s) { + vector counts(26); + for (int i = 0; i < s.size(); ++i) { + ++counts[s[i] - 'a']; + } + for (int i = 0; i < s.size(); ++i) { + if (counts[s[i] - 'a'] == 1) return i; + } + return -1; + } +}; From 3bfd727b00d7ffaadc526871f71c3281cac20eb9 Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Fri, 22 Nov 2024 20:38:48 +0900 Subject: [PATCH 03/10] add Ex1.cpp --- .../Ex1.cpp | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 01-15/4.First Unique Character in a String/Ex1.cpp diff --git a/01-15/4.First Unique Character in a String/Ex1.cpp b/01-15/4.First Unique Character in a String/Ex1.cpp new file mode 100644 index 0000000..fbcfa0c --- /dev/null +++ b/01-15/4.First Unique Character in a String/Ex1.cpp @@ -0,0 +1,74 @@ +#include +#if __has_include("../debug.hpp") +#include "../debug.hpp" +#endif +// ここまでローカルでのデバッグ用なので気にしないでください -------------------- + +#include + +using namespace std; + +// <時間> +// Ex2も併せて13分 +// <疑問・不安点(・個人的な感想、違う意見があれば教えてほしいもの)> +// - 2バージョン作っている。 +// Ex2の方がメモリもコード量も好きなのだが、アクロバティックなので +// 可読性大丈夫かな…と思って無印の方も残している。 +// なお、intの代わりにsize_tを使えばフラグと値の範囲が実際被ることはない。 +// string::nposだってstatic_cast(-1)である。 + +// なお以下で出てくるコメントはプロダクト版にも書くつもりのコメント +class SolutionStream { + public: + SolutionStream() : is_repeated(26), last_indexes(26, -1), index(0) {} + + int firstUniqChar(char c) { + int alpha = c - 'a'; + if (last_indexes[alpha] == -1) { + last_indexes[alpha] = index; + } else { + is_repeated[alpha] = true; + } + + int min_index = INT_MAX; + for (int alpha = 0; alpha < 26; ++alpha) { + if (last_indexes[alpha] != -1 && !is_repeated[alpha]) { + min_index = min(min_index, last_indexes[alpha]); + } + } + + return min_index != INT_MAX ? min_index : -1; + } + + private: + vector is_repeated; + vector last_indexes; + int index; +}; + +class SolutionStream2 { + public: + SolutionStream2() : first_index_or_repeated(26, kNotUsed), index(0) {} + + int firstUniqChar(char c) { + int alpha = c - 'a'; + if (first_index_or_repeated[alpha] == kNotUsed) { + first_index_or_repeated[alpha] = index; + } else { + first_index_or_repeated[alpha] = kRepeated; + } + ++index; + + auto first_index = *min_element( + first_index_or_repeated.begin(), first_index_or_repeated.end() + ); + + return first_index < index ? first_index : -1; + } + + private: + static constexpr int kNotUsed = INT_MAX - 1; + static constexpr int kRepeated = INT_MAX - 1; + vector first_index_or_repeated; + int index; +}; From 955e81b33a5364c18f2dc0ebbad7ed4644477ca3 Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Fri, 22 Nov 2024 20:40:12 +0900 Subject: [PATCH 04/10] fix typo --- 01-15/4.First Unique Character in a String/Ex1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/01-15/4.First Unique Character in a String/Ex1.cpp b/01-15/4.First Unique Character in a String/Ex1.cpp index fbcfa0c..0e0b51b 100644 --- a/01-15/4.First Unique Character in a String/Ex1.cpp +++ b/01-15/4.First Unique Character in a String/Ex1.cpp @@ -67,7 +67,7 @@ class SolutionStream2 { } private: - static constexpr int kNotUsed = INT_MAX - 1; + static constexpr int kNotUsed = INT_MAX; static constexpr int kRepeated = INT_MAX - 1; vector first_index_or_repeated; int index; From 31ea5a28ec95b8007d3b5ba693e6bbd4eca153a9 Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Fri, 22 Nov 2024 20:41:09 +0900 Subject: [PATCH 05/10] improve comment --- 01-15/4.First Unique Character in a String/Ex1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/01-15/4.First Unique Character in a String/Ex1.cpp b/01-15/4.First Unique Character in a String/Ex1.cpp index 0e0b51b..ada4d6d 100644 --- a/01-15/4.First Unique Character in a String/Ex1.cpp +++ b/01-15/4.First Unique Character in a String/Ex1.cpp @@ -12,7 +12,7 @@ using namespace std; // Ex2も併せて13分 // <疑問・不安点(・個人的な感想、違う意見があれば教えてほしいもの)> // - 2バージョン作っている。 -// Ex2の方がメモリもコード量も好きなのだが、アクロバティックなので +// Ex2の方がメモリもコード量も少なくて好きなのだが、アクロバティックなので // 可読性大丈夫かな…と思って無印の方も残している。 // なお、intの代わりにsize_tを使えばフラグと値の範囲が実際被ることはない。 // string::nposだってstatic_cast(-1)である。 From 525a314bf00a288e6811fdcd0f2387ab591f7eea Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Fri, 22 Nov 2024 21:15:18 +0900 Subject: [PATCH 06/10] add comment --- 01-15/4.First Unique Character in a String/Ex1.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/01-15/4.First Unique Character in a String/Ex1.cpp b/01-15/4.First Unique Character in a String/Ex1.cpp index ada4d6d..4a18f17 100644 --- a/01-15/4.First Unique Character in a String/Ex1.cpp +++ b/01-15/4.First Unique Character in a String/Ex1.cpp @@ -8,6 +8,7 @@ using namespace std; +// こちらは番外編です。入力がstreamだったときです。 // <時間> // Ex2も併せて13分 // <疑問・不安点(・個人的な感想、違う意見があれば教えてほしいもの)> From 58cd731db2c6b9fc2540e466a4cd61b5006b35e9 Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Sun, 9 Feb 2025 00:26:17 +0900 Subject: [PATCH 07/10] add 3.cpp --- .../3.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 01-15/4.First Unique Character in a String/3.cpp diff --git a/01-15/4.First Unique Character in a String/3.cpp b/01-15/4.First Unique Character in a String/3.cpp new file mode 100644 index 0000000..ad76aa6 --- /dev/null +++ b/01-15/4.First Unique Character in a String/3.cpp @@ -0,0 +1,26 @@ +#if __has_include("../../debug.hpp") +#include "../../debug.hpp" +#endif +// ここまでローカルでのデバッグ用なので気にしないでください -------------------- + +#include + +using namespace std; + +// <時間> +// 1分 +// <疑問・不安点(・個人的な感想、違う意見があれば教えてほしいもの)> +class Solution { + public: + int firstUniqChar(string s) { + int alphabet_to_count[26]; + fill(alphabet_to_count, alphabet_to_count + 26, 0); + for (auto c : s) { + ++alphabet_to_count[c - 'a']; + } + for (int i = 0; i < s.size(); ++i) { + if (alphabet_to_count[s[i] - 'a'] == 1) return i; + } + return -1; + } +}; From 4038ec55787f0d630176e361dc34098c6233757b Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Sun, 9 Feb 2025 00:59:49 +0900 Subject: [PATCH 08/10] add Ex2.cpp --- .../Ex2.cpp | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 01-15/4.First Unique Character in a String/Ex2.cpp diff --git a/01-15/4.First Unique Character in a String/Ex2.cpp b/01-15/4.First Unique Character in a String/Ex2.cpp new file mode 100644 index 0000000..600608c --- /dev/null +++ b/01-15/4.First Unique Character in a String/Ex2.cpp @@ -0,0 +1,75 @@ +#if __has_include("../../debug.hpp") +#include "../../debug.hpp" +#endif +// ここまでローカルでのデバッグ用なので気にしないでください -------------------- + +#include +#include +#include + +using namespace std; + +// こちらは番外編です。入力がintのstreamだったときです。 +// <時間> +// 15分 +// <疑問・不安点(・個人的な感想、違う意見があれば教えてほしいもの)> +// - 若干分かりにくかったが、もう一度書き直したらわかりやすくなった +class SolutionStream { + public: + int firstUniqueNum(int num) { + if (duplicated_numbers.contains(num)) { + if (numbers.empty()) throw new range_error("No unique number was found"); + return numbers.front(); + } + + if (auto it = unique_numbers.find(num); it != unique_numbers.end()) { + unique_numbers.erase(it); + duplicated_numbers.insert(num); + } else { + unique_numbers.insert(num); + numbers.push(num); + } + + while (!numbers.empty() && duplicated_numbers.contains(numbers.front())) { + numbers.pop(); + } + + if (numbers.empty()) throw new range_error("No unique number was found"); + return numbers.front(); + } + + private: + queue numbers; + set unique_numbers; + set duplicated_numbers; +}; + +// <時間> +// 不明 +// <疑問・不安点(・個人的な感想、違う意見があれば教えてほしいもの)> +class SolutionStream2 { + public: + int firstUniqueNum(int num) { + if (duplicated_numbers.contains(num)) { + if (numbers.empty()) throw new range_error("No unique number was found"); + return numbers.front(); + } + if (auto it = unique_numbers.find(num); it != unique_numbers.end()) { + unique_numbers.erase(it); + duplicated_numbers.insert(num); + while (!numbers.empty() && duplicated_numbers.contains(numbers.front())) { + numbers.pop(); + } + if (numbers.empty()) throw new range_error("No unique number was found"); + } else { + unique_numbers.insert(num); + numbers.push(num); + } + return numbers.front(); + } + + private: + queue numbers; + set unique_numbers; + set duplicated_numbers; +}; From bb066817903f4bf3458acdf2047c73c3c2211507 Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Tue, 15 Apr 2025 12:07:15 +0900 Subject: [PATCH 09/10] add readme --- 01-15/4.First Unique Character in a String/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 01-15/4.First Unique Character in a String/README.md diff --git a/01-15/4.First Unique Character in a String/README.md b/01-15/4.First Unique Character in a String/README.md new file mode 100644 index 0000000..73052f9 --- /dev/null +++ b/01-15/4.First Unique Character in a String/README.md @@ -0,0 +1,3 @@ +# 387. First Unique Character in a String + + From 96b8cad434b04e4aab85eddf41d0ec8457954d80 Mon Sep 17 00:00:00 2001 From: philip82148 <92205270+philip82148@users.noreply.github.com> Date: Tue, 15 Apr 2025 12:08:18 +0900 Subject: [PATCH 10/10] use hyphens instead of spaces for folder name --- .../1.cpp | 0 .../2.cpp | 0 .../3.cpp | 0 .../Ex1.cpp | 0 .../Ex2.cpp | 0 .../README.md | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename 01-15/{4.First Unique Character in a String => 4.First-Unique-Character-in-a-String}/1.cpp (100%) rename 01-15/{4.First Unique Character in a String => 4.First-Unique-Character-in-a-String}/2.cpp (100%) rename 01-15/{4.First Unique Character in a String => 4.First-Unique-Character-in-a-String}/3.cpp (100%) rename 01-15/{4.First Unique Character in a String => 4.First-Unique-Character-in-a-String}/Ex1.cpp (100%) rename 01-15/{4.First Unique Character in a String => 4.First-Unique-Character-in-a-String}/Ex2.cpp (100%) rename 01-15/{4.First Unique Character in a String => 4.First-Unique-Character-in-a-String}/README.md (100%) diff --git a/01-15/4.First Unique Character in a String/1.cpp b/01-15/4.First-Unique-Character-in-a-String/1.cpp similarity index 100% rename from 01-15/4.First Unique Character in a String/1.cpp rename to 01-15/4.First-Unique-Character-in-a-String/1.cpp diff --git a/01-15/4.First Unique Character in a String/2.cpp b/01-15/4.First-Unique-Character-in-a-String/2.cpp similarity index 100% rename from 01-15/4.First Unique Character in a String/2.cpp rename to 01-15/4.First-Unique-Character-in-a-String/2.cpp diff --git a/01-15/4.First Unique Character in a String/3.cpp b/01-15/4.First-Unique-Character-in-a-String/3.cpp similarity index 100% rename from 01-15/4.First Unique Character in a String/3.cpp rename to 01-15/4.First-Unique-Character-in-a-String/3.cpp diff --git a/01-15/4.First Unique Character in a String/Ex1.cpp b/01-15/4.First-Unique-Character-in-a-String/Ex1.cpp similarity index 100% rename from 01-15/4.First Unique Character in a String/Ex1.cpp rename to 01-15/4.First-Unique-Character-in-a-String/Ex1.cpp diff --git a/01-15/4.First Unique Character in a String/Ex2.cpp b/01-15/4.First-Unique-Character-in-a-String/Ex2.cpp similarity index 100% rename from 01-15/4.First Unique Character in a String/Ex2.cpp rename to 01-15/4.First-Unique-Character-in-a-String/Ex2.cpp diff --git a/01-15/4.First Unique Character in a String/README.md b/01-15/4.First-Unique-Character-in-a-String/README.md similarity index 100% rename from 01-15/4.First Unique Character in a String/README.md rename to 01-15/4.First-Unique-Character-in-a-String/README.md