File tree Expand file tree Collapse file tree 8 files changed +298
-0
lines changed Expand file tree Collapse file tree 8 files changed +298
-0
lines changed Original file line number Diff line number Diff line change 1+ /* 
2+ Solve Time: 4:20 
3+ 
4+ Time: O(n) 
5+ Space: O(1) 
6+ 
7+ 一回の走査で解けないかを軽く模索したが思いつかなかったので愚直にmapで記録し、二回ループする手法で解いた。 
8+ 一回の走査で解くことに固執しかけて時間を無駄に思想になっていたため、そこに気づけた点が個人的によかった 
9+ */ 
10+ class  Solution  {
11+  public: 
12+   int  firstUniqChar (string s) {
13+     map<char , int > character_to_count;
14+     for  (const  auto & c : s) {
15+       character_to_count[c]++;
16+     }
17+     for  (int  i = 0 ; i < s.size () ; i++) {
18+       if  (character_to_count[s[i]] == 1 ) {
19+         return  i;
20+       }
21+     }
22+     return  -1 ;
23+   }
24+ };
Original file line number Diff line number Diff line change 1+ /* 
2+ Time: O(n) 
3+ Space: O(1) 
4+ 
5+ step1の改良、マジックナンバーを定数にした 
6+ */ 
7+ class  Solution  {
8+ public: 
9+   int  firstUniqChar (string s) {
10+     map<char , int > character_to_count;
11+     for  (const  auto & c : s) {
12+       character_to_count[c]++;
13+     }
14+     for  (int  i = 0 ; i < s.size (); i++) {
15+       if  (character_to_count[s[i]] == 1 ) {
16+         return  i;
17+       }
18+     }
19+ 
20+     int  const  kNotFound  = -1 ;
21+     return  kNotFound ;
22+   }
23+ };
Original file line number Diff line number Diff line change 1+ /* 
2+ Time : O(N log N) 
3+ Space : O(N) 
4+ 
5+ https://github.com/kazukiii/leetcode/pull/16/files#diff-f400dc0fa41a78f5b2a9ec5c2d5364dd8cf0da8dc9e8c39d15f52f98ea05394b 
6+ を参考にした解法。 
7+ 平衡木(mapのkey)を利用して文字の初出インデックスを管理。 
8+ 二度目の出現でインデックスを削除することで、平衡木の先頭には一度しか出現していない文字のインデックスが残る。 
9+ 3度以上の出現で削除した要素が復帰してしまうが、インデックスが大きいため結果に影響しない。 
10+ */ 
11+ class  Solution  {
12+ public: 
13+   int  firstUniqChar (string s) {
14+     map<char , int > character_to_first_index;
15+     map<int , char > index_to_character;
16+     for  (int  i = 0 ; i < s.size (); i++) {
17+       char  c = s[i];
18+       if  (character_to_first_index.contains (c)) {
19+         int  first_index = character_to_first_index[c];
20+         index_to_character.erase (first_index);
21+         continue ;
22+       }
23+       character_to_first_index[c] = i;
24+       index_to_character[i] = c;
25+     }
26+     if  (index_to_character.empty ()) {
27+       const  int  kNotFound  = -1 ;
28+       return  kNotFound ;
29+     }
30+     return  index_to_character.begin ()->first ;
31+   }
32+ };
Original file line number Diff line number Diff line change 1+ /* 
2+ https://github.com/colorbox/leetcode/pull/29#discussion_r1861430039 
3+ を見てそれを参考に自分で書いた解法、比較用 
4+ */ 
5+ class  Solution  {
6+  public: 
7+   int  firstUniqChar (string s) {
8+     queue<CharacterAndCount> queue;
9+     map<char , int > character_to_count;
10+     for  (int  i = 0 ; i < s.size (); i++) {
11+       char  c = s[i];
12+       character_to_count[c]++;
13+       queue.push ({c, i});
14+       while  (true ) {
15+         char  front_character = queue.front ().character ;
16+         if  (character_to_count[front_character] > 1 ) {
17+           queue.pop ();
18+         } else  {
19+           break ;
20+         }
21+       }
22+     }
23+     if  (queue.empty ()) {
24+       return  -1 ;
25+     }
26+     return  queue.front ().index ;
27+   }
28+ 
29+  private: 
30+   struct  CharacterAndCount  {
31+     char  character;
32+     int  index;
33+   };
34+ };
Original file line number Diff line number Diff line change 1+ /* 
2+ step2_2_suggested.cpp 
3+ を 
4+ https://github.com/colorbox/leetcode/pull/29#discussion_r1861430039 
5+ の書き方に沿って修正したコード、参照用 
6+ */ 
7+ class  Solution  {
8+  public: 
9+   int  firstUniqChar (string s) {
10+     queue<CharacterAndCount> characters;
11+     map<char , int > character_to_count;
12+     for  (int  i = 0 ; i < s.size (); ++i) {
13+       char  c = s[i];
14+       ++character_to_count[c];
15+       characters.push ({c, i});
16+       while  (character_to_count[characters.front ().character ] >= 2 ) {
17+         characters.pop ();
18+       }
19+     }
20+     if  (characters.empty ()) {
21+       return  -1 ;
22+     }
23+     return  characters.front ().index ;
24+   }
25+ 
26+  private: 
27+   struct  CharacterAndCount  {
28+     char  character;
29+     int  index;
30+   };
31+ };
Original file line number Diff line number Diff line change 1+ /* 
2+ Time : O(N log N) 
3+ Space : O(N) 
4+ 
5+ https://github.com/kazukiii/leetcode/pull/16/files#diff-f5b3276a9df261ed1c1e70d5b6de00ca4544e1a1ae1de6a466add8df5cd3d1b0 
6+ を参考にした解法。 
7+ ソートで文字種ごとに隣接させ、二度以上出現したものを除外し、min比較で最小インデックスを求める。 
8+ */ 
9+ class  Solution  {
10+ public: 
11+   int  firstUniqChar (string s) {
12+     vector<CharacterIndex> character_indices;
13+     for  (int  i = 0 ; i < s.size (); i++) {
14+       character_indices.push_back ({s[i], i});
15+     }
16+     sort (character_indices.begin (), character_indices.end ());
17+     int  count = 1 ;
18+     int  first_unique_character_index = numeric_limits<int >::max ();
19+     for  (int  i = 0 ; i < s.size (); i++) {
20+       if  (i < s.size () - 1  && character_indices[i].character  == character_indices[i + 1 ].character ) {
21+         count++;
22+         continue ;
23+       }
24+       if  (count == 1 ) {
25+         first_unique_character_index = min (first_unique_character_index, character_indices[i].index );
26+       }
27+       count = 1 ;
28+     }
29+     if  (first_unique_character_index == numeric_limits<int >::max ()) {
30+       return  -1 ;
31+     }
32+     return  first_unique_character_index;
33+   }
34+ 
35+   struct  CharacterIndex  {
36+     char  character;
37+     int  index;
38+ 
39+     bool  operator <(const  CharacterIndex& other) {
40+       return  character < other.character ;
41+     }
42+   };
43+ };
Original file line number Diff line number Diff line change 1+ /* 
2+ Time : O(N) 
3+ Space : O(1) 
4+ 
5+ LRUを応用してできるとのことだったので実装。 
6+ https://www.geeksforgeeks.org/lru-cache-implementation-using-double-linked-lists/ 
7+ 本質的に平衡木による解法と大差ない気がする。 
8+ */ 
9+ struct  Node  {
10+   int  index;
11+   int  count;
12+   Node* prev;
13+   Node* next;
14+ 
15+   explicit  Node (int  i) {
16+     index = i;
17+     count = 1 ;
18+     prev = nullptr ;
19+     next = nullptr ;
20+   }
21+ };
22+ 
23+ class  LRUCache  {
24+  public: 
25+   Node* head;
26+   Node* tail;
27+   map<char , Node*> character_to_node;
28+ 
29+   LRUCache () {
30+     head = new  Node (numeric_limits<int >::max ());
31+     tail = new  Node (numeric_limits<int >::max ());
32+     head->next  = tail;
33+     tail->prev  = head;
34+   }
35+ 
36+   ~LRUCache () {
37+     for  (auto  [_c, node] : character_to_node) {
38+       delete  node;
39+     }
40+     delete  head;
41+     delete  tail;
42+   }
43+ 
44+   void  Put (char  character, int  index) {
45+     if  (character_to_node.contains (character)) {
46+       Node *node = character_to_node[character];
47+       Remove (node);
48+       node->count ++;
49+       return ;
50+     }
51+ 
52+     Node *node = new  Node (index);
53+     character_to_node[character] = node;
54+     PushBack (node);
55+   }
56+ 
57+   bool  Empty () {
58+     return  head->next ->index  == tail->index ;
59+   }
60+ 
61+  private: 
62+   void  Remove (Node* node) {
63+     if  (node->prev  == nullptr ) {
64+       return ;
65+     }
66+     Node* prev = node->prev ;
67+     Node* next = node->next ;
68+     prev->next  = next;
69+     next->prev  = prev;
70+     node->prev  = nullptr ;
71+     node->next  = nullptr ;
72+   }
73+ 
74+   void  PushBack (Node* node) {
75+     Node* prev = tail->prev ;
76+     prev->next  = node;
77+     node->prev  = prev;
78+     node->next  = tail;
79+     tail->prev  = node;
80+   }
81+ };
82+ 
83+ class  Solution  {
84+  public: 
85+   int  firstUniqChar (string s) {
86+     LRUCache cache = LRUCache ();
87+     for  (int  i = 0 ; i < s.size (); i++) {
88+       cache.Put (s[i], i);
89+     }
90+     if  (cache.Empty () || cache.head ->next ->count  > 1 ) {
91+       return  -1 ;
92+     }
93+     return  cache.head ->next ->index ;
94+   }
95+ };
96+ 
Original file line number Diff line number Diff line change 1+ class  Solution  {
2+ public: 
3+   int  firstUniqChar (string s) {
4+     map<char , int > character_to_count;
5+     for  (const  char & c : s) {
6+       character_to_count[c]++;
7+     }
8+     for  (int  i = 0 ; i < s.size (); i++) {
9+       if  (character_to_count[s[i]] == 1 ) {
10+         return  i;
11+       }
12+     }
13+     return  -1 ;
14+   }
15+ };
 
 
   
 
     
   
   
          
    
    
     
    
      
     
     
    You can’t perform that action at this time.
  
 
    
  
    
      
        
     
       
      
     
   
 
    
    
  
 
  
 
     
    
0 commit comments