双指针 
      
    
      
      
      
        字符串 
      
    
   
  
    
      
       
     
  
  
    
      
    
    
      
       
     
  
题目描述 
神奇字符串 s 仅由 '1' 和 '2' 组成,并需要遵守下面的规则:
    神奇字符串 s 的神奇之处在于,串联字符串中 '1' 和 '2' 的连续出现次数可以生成该字符串。 
 
s 的前几个元素是 s = "1221121221221121122……" 。如果将 s 中连续的若干 1 和 2 进行分组,可以得到 "1 22 11 2 1 22 1 22 11 2 11 22 ......" 。每组中 1 或者 2 的出现次数分别是 "1 2 2 1 1 2 1 2 2 1 2 2 ......" 。上面的出现次数正是 s 自身。
给你一个整数 n ,返回在神奇字符串 s 的前 n 个数字中 1 的数目。
 
示例 1: 
输入: n = 6
输出: 3
解释: 神奇字符串 s 的前 6 个元素是 “122112”,它包含三个 1,因此返回 3 。 
 
示例 2: 
输入: n = 1
输出: 1
 
 
提示: 
解法 
方法一:模拟构造过程 
根据题目,我们得知,字符串 \(s\)  的每一组数字都可以由字符串 \(s\)  自身的数字得到。
字符串 \(s\)  前两组数字为 \(1\)  和 \(22\) ,是由字符串 \(s\)  的第一个数字 \(1\)  和第二个数字 \(2\)  得到的,并且第一组数字只包含 \(1\) ,第二组数字只包含 \(2\) ,第三组数字只包含 \(1\) ,以此类推。
由于前两组数字已知,我们初始化字符串 \(s\)  为 \(122\) ,然后从第三组开始构造,第三组数字是由字符串 \(s\)  的第三个数字(下标 \(i=2\) )得到,因此我们此时将指针 \(i\)  指向字符串 \(s\)  的第三个数字 \(2\) 。
指针 \(i\)  指向的数字为 \(2\) ,表示第三组的数字会出现两次,并且,由于前一组数字为 \(2\) ,组之间数字交替出现,因此第三组数字为两个 \(1\) ,即 \(11\) 。构造后,指针 \(i\)  移动到下一个位置,即指向字符串 \(s\)  的第四个数字 \(1\) 。
这时候指针 \(i\)  指向的数字为 \(1\) ,表示第四组的数字会出现一次,并且,由于前一组数字为 \(1\) ,组之间数字交替出现,因此第四组数字为一个 \(2\) ,即 \(2\) 。构造后,指针 \(i\)  移动到下一个位置,即指向字符串 \(s\)  的第五个数字 \(1\) 。
我们按照这个规则,依次模拟构造过程,直到字符串 \(s\)  的长度大于等于 \(n\) 。
时间复杂度 \(O(n)\) ,空间复杂度 \(O(n)\) 。
Python3 Java C++ Go TypeScript Rust 
class   Solution : 
    def   magicalString ( self ,  n :  int )  ->  int : 
        s  =  [ 1 ,  2 ,  2 ] 
        i  =  2 
        while  len ( s )  <  n : 
            pre  =  s [ - 1 ] 
            cur  =  3  -  pre 
            # cur 表示这一组的数字,s[i] 表示这一组数字出现的次数 
            s  +=  [ cur ]  *  s [ i ] 
            i  +=  1 
        return  s [: n ] . count ( 1 ) 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 class  Solution   { 
     public   int   magicalString ( int   n )   { 
         List < Integer >   s   =   new   ArrayList <> ( List . of ( 1 ,   2 ,   2 )); 
         for   ( int   i   =   2 ;   s . size ()   <   n ;   ++ i )   { 
             int   pre   =   s . get ( s . size ()   -   1 ); 
             int   cur   =   3   -   pre ; 
             for   ( int   j   =   0 ;   j   <   s . get ( i );   ++ j )   { 
                 s . add ( cur ); 
             } 
         } 
         int   ans   =   0 ; 
         for   ( int   i   =   0 ;   i   <   n ;   ++ i )   { 
             if   ( s . get ( i )   ==   1 )   { 
                 ++ ans ; 
             } 
         } 
         return   ans ; 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 class   Solution   { 
public : 
     int   magicalString ( int   n )   { 
         vector < int >   s   =   { 1 ,   2 ,   2 }; 
         for   ( int   i   =   2 ;   s . size ()   <   n ;   ++ i )   { 
             int   pre   =   s . back (); 
             int   cur   =   3   -   pre ; 
             for   ( int   j   =   0 ;   j   <   s [ i ];   ++ j )   { 
                 s . emplace_back ( cur ); 
             } 
         } 
         return   count ( s . begin (),   s . begin ()   +   n ,   1 ); 
     } 
}; 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 func   magicalString ( n   int )   ( ans   int )   { 
     s   :=   [] int { 1 ,   2 ,   2 } 
     for   i   :=   2 ;   len ( s )   <   n ;   i ++   { 
         pre   :=   s [ len ( s ) - 1 ] 
         cur   :=   3   -   pre 
         for   j   :=   0 ;   j   <   s [ i ];   j ++   { 
             s   =   append ( s ,   cur ) 
         } 
     } 
     for   _ ,   c   :=   range   s [: n ]   { 
         if   c   ==   1   { 
             ans ++ 
         } 
     } 
     return 
} 
 
 
function   magicalString ( n :   number ) :   number   { 
     const   s :   number []   =   [ 1 ,   2 ,   2 ]; 
     for   ( let   i   =   2 ;   s . length   <   n ;   ++ i )   { 
         let   pre   =   s [ s . length   -   1 ]; 
         let   cur   =   3   -   pre ; 
         for   ( let   j   =   0 ;   j   <   s [ i ];   ++ j )   { 
             s . push ( cur ); 
         } 
     } 
     return   s . slice ( 0 ,   n ). filter ( x   =>   x   ===   1 ). length ; 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 impl   Solution   { 
     pub   fn   magical_string ( n :   i32 )   ->   i32   { 
         let   mut   s   =   vec! [ 1 ,   2 ,   2 ]; 
         let   mut   i   =   2 ; 
         while   s . len ()   <   n   as   usize   { 
             let   pre   =   s [ s . len ()   -   1 ]; 
             let   cur   =   3   -   pre ; 
             for   _   in   0 .. s [ i ]   { 
                 s . push ( cur ); 
             } 
             i   +=   1 ; 
         } 
         s . iter (). take ( n   as   usize ). filter ( |&& x |   x   ==   1 ). count ()   as   i32 
     } 
} 
 
 
 
 
  
  
  
    
    
    
    
      
  
    
      
  
     
   
  GitHub