文章目录  🍺 二分法 🍻 旋转数组 🥂 33. 搜索旋转排序数组 [旋转数组] [目标值] (二分法) 🍻 元素边界 🥂 34. 在排序数组中查找元素的第一个和最后一个位置 [有序数组] > [元素边界] > (二分法) 🥂 81. 搜索旋转排序数组Ⅱ [旋转数组] [有重] [目标值] (二分法) 🥂 153. 寻找旋转排序数组中的最小值 [旋转数组] [最小值] (二分法) 🍺 双指针 🍻 元素合并 🥂 21. 合并两个有序链表 [有序链表] [合并] (双指针) (归并) 🍻 元素交换 🥂 LCR 139. 训练计划 I [数组] [元素交换] (双指针) 🍻 元素相交 🥂 142. 环形链表II [链表] > [环] > (双指针) 🥂 160. 相交链表 [链表] > [相交] > (双指针) 🍻 面积 🥂 11. 盛最多水的容器 [数组] [面积] (双指针) 🥂 42. 接雨水 [数组] [面积] (双指针) 🥂 其他 🥂 31. 下一个排列 [数组] [排列] (双指针) (推导) 🍺 三指针 🍻 链表反转 🥂 25. K 个一组翻转链表 [链表] [分组反转] (三指针) 🥂 92. 反转链表II [链表] [反转] (三指针) 🥂 206. 反转链表 [链表] [反转] (三指针) 🍻 快速排序 🥂 215. 数组中的第K个最大元素 [数组] [第K大元素] (三指针) (快速排序) 🥂 912. 排序数组 [数组] [排序] (三指针) (快速排序) 🍺 滑动窗口 🍻 子串 🥂 3. 无重复字符的最长子串 [字符串] [子串] (滑动窗口) 🍻 区间和 🥂 1423. 可获得的最大点数 [数组] > [区间外最大值] > [区间内最小值] > (定长滑动窗口)   
 
class  Solution  { 
public : int  search ( vector< int > &  nums,  int  target)  { int  n =  nums. size ( ) ; int  left =  0 ,  right =  n -  1 ; while  ( left <=  right)  { int  mid =  left +  ( right -  left)  /  2 ; if  ( nums[ mid]  ==  target)  return  mid; if  ( nums[ mid]  <=  nums[ 0 ] )  { if  ( nums[ mid]  <  target &&  target <=  nums[ n -  1 ] )  { left =  mid +  1 ;          }  else  { right =  mid -  1 ;         } }  else  { if  ( nums[ 0 ]  <=  target &&  target <  nums[ mid] )  { right =  mid -  1 ;         }  else  { left =  mid +  1 ;          } } } return  - 1 ; } 
} ; 
class  Solution  { 
public : vector< int >  searchRange ( vector< int > &  nums,  int  target)  { int  left =  find_l ( nums,  target) ; int  right =  find_r ( nums, target) ; return  { left,  right} ; } int  find_l ( vector< int > &  nums,  int  target)  { int  n =  nums. size ( ) ; int  left =  0 ,  right =  n -  1 ; while  ( left <=  right)  { int  mid =  left +  ( right -  left)  /  2 ; if  ( nums[ mid]  >=  target)  { right =  mid -  1 ; }  else  { left =  mid +  1 ; } } if  ( 0  <=  left &&  left <  n &&  nums[ left]  ==  target)  { return  left; } return  - 1 ; } int  find_r ( vector< int > &  nums,  int  target)  { int  n =  nums. size ( ) ; int  left =  0 ,  right =  n -  1 ; while  ( left <=  right)  { int  mid =  left +  ( right -  left)  /  2 ; if  ( nums[ mid]  >  target)  { right =  mid -  1 ; }  else  { left =  mid +  1 ; } } if  ( 0  <=  right &&  right <  n &&  nums[ right]  ==  target)  { return  right; } return  - 1 ; } 
} ; 
class  Solution  { 
public : bool  search ( vector< int > &  nums,  int  target)  { int  n =  nums. size ( ) ; int  left =  0 ,  right =  n -  1 ; while  ( left <=  right)  { int  mid =  left +  ( right -  left)  /  2 ; if  ( nums[ mid]  ==  target)  return  true ; if  ( nums[ mid]  ==  nums[ left] )  { left++ ; continue ; } if  ( nums[ mid]  ==  nums[ right] )  { right-- ; continue ; } if  ( nums[ mid]  <  nums[ 0 ] )  {   if  ( nums[ mid]  <  target &&  target <=  nums[ n -  1 ] )  { left =  mid +  1 ;      }  else  { right =  mid -  1 ;     } }  else  {                     if  ( nums[ 0 ]  <=  target &&  target <  nums[ mid] )  { right =  mid -  1 ;     }  else  { left =  mid +  1 ;      } } } return  false ; } 
} ; 
class  Solution  { 
public : int  findMin ( vector< int > &  nums)  { int  left =  0 ,  right =  nums. size ( )  -  1 ; while  ( left <=  right)  { int  mid =  left +  ( right -  left)  /  2 ; if  ( nums[ mid]  <  nums[ right] )  { right =  mid; }  else  if  ( nums[ mid]  >  nums[ right] )  { left =  mid +  1 ; }  else  { right-- ; } } return  nums[ left] ; } 
} ; 
class  Solution  { 
public : ListNode*  mergeTwoLists ( ListNode*  list1,  ListNode*  list2)  { ListNode*  dummy =  new  ListNode ( - 1 ) ,  *  cur =  dummy; ListNode*  p1 =  list1,  *  p2 =  list2; while  ( p1 !=  nullptr  &&  p2 !=  nullptr )  { if  ( p1-> val <  p2-> val)  { cur-> next =  p1; p1 =  p1-> next; }  else  { cur-> next =  p2; p2 =  p2-> next; } cur =  cur-> next; } if  ( p1 !=  nullptr )  cur-> next =  p1; if  ( p2 !=  nullptr )  cur-> next =  p2; return  dummy-> next; } 
} ; 
class  Solution  { 
public : vector< int >  trainingPlan ( vector< int > &  actions)  { int  n =  actions. size ( ) ; if  ( n <=  1 )  return  actions; int  left =  0 ,  right =  n -  1 ;              while  ( left <  right)  { while  ( left <  right &&  actions[ left]  %  2  ==  1 )  { left++ ; } while  ( left <  right &&  actions[ right]  %  2  ==  0 )  { right-- ; } std:: swap ( actions[ left] ,  actions[ right] ) ; } return  actions; } 
} ; 
class  Solution  { 
public : ListNode * detectCycle ( ListNode * head)  { ListNode*  dummy =  new  ListNode ( - 1 ) ; dummy-> next =  head; ListNode*  fast =  dummy,  *  slow =  dummy; while  ( fast-> next &&  fast-> next-> next)  { slow =  slow-> next; fast =  fast-> next-> next; if  ( fast ==  slow)  { fast =  dummy; while  ( fast !=  slow)  { slow =  slow-> next; fast =  fast-> next; } return  fast; } } return  nullptr ;    } 
} ; 
class  Solution  { 
public : ListNode * getIntersectionNode ( ListNode * headA,  ListNode * headB)  { ListNode * p1 =  headA,  * p2 =  headB; while  ( p1 !=  p2)  { if  ( p1 ==  nullptr )  p1 =  headB; else  p1 =  p1-> next; if  ( p2 ==  nullptr )  p2 =  headA; else  p2 =  p2-> next; } return  p1; } 
} ; 
class  Solution  { 
public : int  maxArea ( vector< int > &  height)  { int  left =  0 ,  right =  height. size ( )  -  1 ; int  res =  0 ,  cur =  0 ; while  ( left <  right)  { cur =  min ( height[ left] ,  height[ right] )  *  ( right -  left) ; res =  max ( res,  cur) ; if  ( height[ left]  <  height[ right] )  { left++ ; }  else  { right-- ; } } return  res; } 
} ; 
class  Solution  { 
public : int  trap ( vector< int > &  height)  { int  left =  0 ,  right =  height. size ( )  -  1 ; int  left_max =  height[ left] ,  right_max =  height[ right] ; int  cur =  0 ,  res =  0 ; while  ( left <=  right)  { left_max =  max ( left_max,  height[ left] ) ; right_max =  max ( right_max,  height[ right] ) ; if  ( left_max <  right_max)  { res +=  left_max -  height[ left] ; left++ ; }  else  { res +=  right_max -  height[ right] ; right-- ; } } return  res; } 
} ; 
class  Solution  { 
private : int  flag =  0 ;    
public : void  nextPermutation ( vector< int > &  nums)  { int  n =  nums. size ( ) ; int  i =  n -  2 ,  j =  n -  1 ; while  ( i >=  0  &&  nums[ i]  >=  nums[ i +  1 ] )  { i-- ; } if  ( i >=  0 )  { while  ( j >  i &&  nums[ j]  <=  nums[ i] )  { j-- ; } swap ( nums[ i] ,  nums[ j] ) ; reverse ( nums. begin ( )  +  i +  1 ,  nums. end ( ) ) ; }  else  { reverse ( nums. begin ( ) ,  nums. end ( ) ) ; } return ; } 
} ; 
class  Solution  { 
public : ListNode*  reverseKGroup ( ListNode*  head,  int  k)  { ListNode*  dummy =  new  ListNode ( - 1 ) ;      dummy-> next =  head; ListNode*  pre =  dummy,  *  end =  dummy; while  ( end-> next !=  nullptr )  { for  ( int  i =  0 ;  i <  k &&  end !=  nullptr ;  ++ i)  { end =  end-> next; } if  ( end ==  nullptr )  break ; ListNode*  start =  pre-> next,  *  next =  end-> next; end-> next =  nullptr ; pre-> next =  reverse ( start) ; start-> next =  next; pre =  start; end =  start; } return  dummy-> next; } ListNode*  reverse ( ListNode*  head)  { ListNode*  pre =  nullptr ; ListNode*  cur =  head; while  ( cur !=  nullptr )  { ListNode*  next =  cur-> next; cur-> next =  pre; pre =  cur; cur =  next; } return  pre; }  
} ; 
class  Solution  { 
public : ListNode*  reverseBetween ( ListNode*  head,  int  left,  int  right)  { ListNode*  dummy =  new  ListNode ( - 1 ) ; dummy-> next =  head; ListNode*  pre =  dummy,  *  end =  dummy; for  ( int  i =  0 ;  i <  left -  1 ;  ++ i)  pre =  pre-> next; cout <<  pre-> val; for  ( int  j =  0 ;  j <  right;  ++ j)  end =  end-> next; ListNode*  start =  pre-> next,  *  next =  end-> next; end-> next =  nullptr ; pre-> next =  reverse ( start) ; start-> next =  next; return  dummy-> next; } ListNode*  reverse ( ListNode*  head)  { ListNode*  pre =  nullptr ; ListNode*  cur =  head; while  ( cur !=  nullptr )  { ListNode*  next =  cur-> next; cur-> next =  pre; pre =  cur; cur =  next; } return  pre; } 
} ; 
class  Solution  { 
public : ListNode*  reverseList ( ListNode*  head)  { return  reverse ( head) ; } ListNode*  reverse ( ListNode*  head)  { ListNode*  pre =  nullptr ; ListNode*  cur =  head; while  ( cur !=  nullptr )  { ListNode*  next =  cur-> next; cur-> next =  pre; pre =  cur; cur =  next; } return  pre; } 
} ; 
class  Solution  { 
private : int  target;  int  res;     
public : int  findKthLargest ( vector< int > &  nums,  int  k)  { int  n =  nums. size ( ) ; target =  n -  k; quickSort ( nums,  0 ,  n -  1 ) ; return  res; } void  quickSort ( vector< int > &  nums,  int  left,  int  right)  { if  ( left >  right)  return ; if  ( left ==  right &&  left ==  target)  { res =  nums[ target] ; return ; } vector< int >  edge =  part ( nums,  left,  right) ; if  ( edge[ 0 ]  <=  target &&  target <=  edge[ 1 ] )  { res =  nums[ target] ; return ; } quickSort ( nums,  left,  edge[ 0 ]  -  1 ) ; quickSort ( nums,  edge[ 1 ]  +  1 ,  right) ; } vector< int >  part ( vector< int > &  nums,  int  left,  int  right)  { int  pivot_idx =  rand ( )  %  ( right -  left +  1 )  +  left; int  pivot =  nums[ pivot_idx] ; swap ( nums[ pivot_idx] ,  nums[ left] ) ; int  curp =  left +  1 ,  leftp =  left,  rightp =  right +  1 ; while  ( curp <  rightp)  { if  ( nums[ curp]  <  pivot)  {            leftp++ ; swap ( nums[ curp] ,  nums[ leftp] ) ; curp++ ; }  else  if  ( nums[ curp]  >  pivot)  {     rightp-- ; swap ( nums[ curp] ,  nums[ rightp] ) ; }  else  {                             curp++ ; } } swap ( nums[ left] ,  nums[ leftp] ) ; return  { leftp,  rightp -  1 } ; } 
} ; 
class  Solution  { 
public : vector< int >  sortArray ( vector< int > &  nums)  { int  n =  nums. size ( ) ; quickSort ( nums,  0 ,  n -  1 ) ; return  nums; } void  quickSort ( vector< int > &  nums,  int  left,  int  right)  { if  ( left >  right)  return ; vector< int >  edge =  part ( nums,  left,  right) ; quickSort ( nums,  left,  edge[ 0 ]  -  1 ) ; quickSort ( nums,  edge[ 1 ]  +  1 ,  right) ; } vector< int >  part ( vector< int > &  nums,  int  left,  int  right)  { int  pivot_idx =  rand ( )  %  ( right -  left +  1 )  +  left; int  pivot =  nums[ pivot_idx] ; swap ( nums[ pivot_idx] ,  nums[ left] ) ; int  curp =  left +  1 ,  leftp =  left,  rightp =  right +  1 ; while  ( curp <  rightp)  { if  ( nums[ curp]  <  pivot)  {            leftp++ ; swap ( nums[ curp] ,  nums[ leftp] ) ; curp++ ; }  else  if  ( nums[ curp]  >  pivot)  {     rightp-- ; swap ( nums[ curp] ,  nums[ rightp] ) ; }  else  {                             curp++ ; } } swap ( nums[ left] ,  nums[ leftp] ) ; return  { leftp,  rightp -  1 } ; } 
} ; 
class  Solution  { 
private : unordered_map< char ,  int >  umap;       int  res =  0 ;                         
public : int  lengthOfLongestSubstring ( string s)  { int  n =  s. size ( ) ; int  left =  0 ,  right =  0 ;         while  ( right <  n)  { char  cur_r =  s[ right++ ] ;     umap[ cur_r] ++ ;               while  ( umap[ cur_r]  >  1 )  { char  cur_l =  s[ left++ ] ; umap[ cur_l] -- ; } res =  max ( res,  right -  left) ; } return  res; } 
} ; 
class  Solution  { 
public : int  maxScore ( vector< int > &  cardPoints,  int  k)  { int  n =  cardPoints. size ( ) ; int  windowSize =  n -  k; int  sum =  accumulate ( cardPoints. begin ( ) ,  cardPoints. begin ( )  +  windowSize,  0 ) ; int  min_val =  sum;           for  ( int  i =  0 ;  i <  n -  windowSize;  ++ i)  { int  left =  i,  right =  i +  windowSize; sum +=  cardPoints[ right]  -  cardPoints[ left] ; min_val =  min ( min_val,  sum) ; } return  accumulate ( cardPoints. begin ( ) ,  cardPoints. end ( ) ,  0 )  -  min_val; } 
} ;