双指针 
      
    
      
      
      
        排序 
      
    
      
      
      
        数组 
      
    
   
  
    
      
       
     
  
  
    
      
    
    
      
       
     
  
题目描述 
给定一个包含红色、白色和蓝色、共 n  个元素的数组  nums ,原地   对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
 
示例 1: 
输入: nums = [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
 
示例 2: 
输入: nums = [2,0,1]
输出: [0,1,2]
 
 
提示: 
    n == nums.length 
    1 <= n <= 300 
    nums[i] 为 0、1 或 2 
 
 
进阶: 
解法 
方法一:三指针 
我们定义三个指针 \(i\) , \(j\)  和 \(k\) ,其中指针 \(i\)  用于指向数组中元素值为 \(0\)  的最右边界,指针 \(j\)  用于指向数组中元素值为 \(2\)  的最左边界,初始时 \(i=-1\) , \(j=n\) 。指针 \(k\)  用于指向当前遍历的元素,初始时 \(k=0\) 。
当 \(k \lt j\)  时,我们执行如下操作:
若 \(nums[k]=0\) ,则将其与 \(nums[i+1]\)  交换,然后 \(i\)  和 \(k\)  都加 \(1\) ; 
若 \(nums[k]=2\) ,则将其与 \(nums[j-1]\)  交换,然后 \(j\)  减 \(1\) ; 
若 \(nums[k]=1\) ,则 \(k\)  加 \(1\) 。 
 
遍历结束后,数组中的元素就被分成了 \([0,i]\) , \([i+1,j-1]\)  和 \([j,n-1]\)  三个部分。
时间复杂度 \(O(n)\) ,其中 \(n\)  是数组的长度。只需要遍历一遍数组即可。空间复杂度 \(O(1)\) 。
Python3 Java C++ Go TypeScript Rust C# 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 class   Solution : 
    def   sortColors ( self ,  nums :  List [ int ])  ->  None : 
        i ,  j ,  k  =  - 1 ,  len ( nums ),  0 
        while  k  <  j : 
            if  nums [ k ]  ==  0 : 
                i  +=  1 
                nums [ i ],  nums [ k ]  =  nums [ k ],  nums [ i ] 
                k  +=  1 
            elif  nums [ k ]  ==  2 : 
                j  -=  1 
                nums [ j ],  nums [ k ]  =  nums [ k ],  nums [ j ] 
            else : 
                k  +=  1 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 class  Solution   { 
     public   void   sortColors ( int []   nums )   { 
         int   i   =   - 1 ,   j   =   nums . length ,   k   =   0 ; 
         while   ( k   <   j )   { 
             if   ( nums [ k ]   ==   0 )   { 
                 swap ( nums ,   ++ i ,   k ++ ); 
             }   else   if   ( nums [ k ]   ==   2 )   { 
                 swap ( nums ,   -- j ,   k ); 
             }   else   { 
                 ++ k ; 
             } 
         } 
     } 
     private   void   swap ( int []   nums ,   int   i ,   int   j )   { 
         int   t   =   nums [ i ] ; 
         nums [ i ]   =   nums [ j ] ; 
         nums [ j ]   =   t ; 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 class   Solution   { 
public : 
     void   sortColors ( vector < int >&   nums )   { 
         int   i   =   -1 ,   j   =   nums . size (),   k   =   0 ; 
         while   ( k   <   j )   { 
             if   ( nums [ k ]   ==   0 )   { 
                 swap ( nums [ ++ i ],   nums [ k ++ ]); 
             }   else   if   ( nums [ k ]   ==   2 )   { 
                 swap ( nums [ -- j ],   nums [ k ]); 
             }   else   { 
                 ++ k ; 
             } 
         } 
     } 
}; 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 func   sortColors ( nums   [] int )   { 
     i ,   j ,   k   :=   - 1 ,   len ( nums ),   0 
     for   k   <   j   { 
         if   nums [ k ]   ==   0   { 
             i ++ 
             nums [ i ],   nums [ k ]   =   nums [ k ],   nums [ i ] 
             k ++ 
         }   else   if   nums [ k ]   ==   2   { 
             j -- 
             nums [ j ],   nums [ k ]   =   nums [ k ],   nums [ j ] 
         }   else   { 
             k ++ 
         } 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 /** 
 Do not return anything, modify nums in-place instead. 
 */ 
function   sortColors ( nums :   number []) :   void   { 
     let   i   =   - 1 ; 
     let   j   =   nums . length ; 
     let   k   =   0 ; 
     while   ( k   <   j )   { 
         if   ( nums [ k ]   ===   0 )   { 
             ++ i ; 
             [ nums [ i ],   nums [ k ]]   =   [ nums [ k ],   nums [ i ]]; 
             ++ k ; 
         }   else   if   ( nums [ k ]   ===   2 )   { 
             -- j ; 
             [ nums [ j ],   nums [ k ]]   =   [ nums [ k ],   nums [ j ]]; 
         }   else   { 
             ++ k ; 
         } 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 impl   Solution   { 
     pub   fn   sort_colors ( nums :   & mut   Vec < i32 > )   { 
         let   mut   i   =   - 1 ; 
         let   mut   j   =   nums . len (); 
         let   mut   k   =   0 ; 
         while   k   <   j   { 
             if   nums [ k ]   ==   0   { 
                 i   +=   1 ; 
                 nums . swap ( i   as   usize ,   k   as   usize ); 
                 k   +=   1 ; 
             }   else   if   nums [ k ]   ==   2   { 
                 j   -=   1 ; 
                 nums . swap ( j ,   k ); 
             }   else   { 
                 k   +=   1 ; 
             } 
         } 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 public   class   Solution   { 
     public   void   SortColors ( int []   nums )   { 
         int   i   =   - 1 ,   j   =   nums . Length ,   k   =   0 ; 
         while   ( k   <   j )   { 
             if   ( nums [ k ]   ==   0 )   { 
                 swap ( nums ,   ++ i ,   k ++ ); 
             }   else   if   ( nums [ k ]   ==   2 )   { 
                 swap ( nums ,   -- j ,   k ); 
             }   else   { 
                 ++ k ; 
             } 
         } 
     } 
     private   void   swap ( int []   nums ,   int   i ,   int   j )   { 
         int   t   =   nums [ i ]; 
         nums [ i ]   =   nums [ j ]; 
         nums [ j ]   =   t ; 
     } 
}