文章目录 🍺 二分法 🍻 旋转数组 🥂 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. 可获得的最大点数 [数组] > [区间外最大值] > [区间内最小值] > (定长滑动窗口)
🍺 二分法
🍻 旋转数组
🥂 33. 搜索旋转排序数组 [旋转数组] [目标值] (二分法)
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 ; }
} ;
🍻 元素边界
🥂 34. 在排序数组中查找元素的第一个和最后一个位置 [有序数组] > [元素边界] > (二分法)
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 ; }
} ;
🥂 81. 搜索旋转排序数组Ⅱ [旋转数组] [有重] [目标值] (二分法)
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 ; }
} ;
🥂 153. 寻找旋转排序数组中的最小值 [旋转数组] [最小值] (二分法)
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] ; }
} ;
🍺 双指针
🍻 元素合并
🥂 21. 合并两个有序链表 [有序链表] [合并] (双指针) (归并)
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; }
} ;
🍻 元素交换
🥂 LCR 139. 训练计划 I [数组] [元素交换] (双指针)
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; }
} ;
🍻 元素相交
🥂 142. 环形链表II [链表] > [环] > (双指针)
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 ; }
} ;
🥂 160. 相交链表 [链表] > [相交] > (双指针)
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; }
} ;
🍻 面积
🥂 11. 盛最多水的容器 [数组] [面积] (双指针)
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; }
} ;
🥂 42. 接雨水 [数组] [面积] (双指针)
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; }
} ;
🥂 其他
🥂 31. 下一个排列 [数组] [排列] (双指针) (推导)
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 ; }
} ;
🍺 三指针
🍻 链表反转
🥂 25. K 个一组翻转链表 [链表] [分组反转] (三指针)
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; }
} ;
🥂 92. 反转链表II [链表] [反转] (三指针)
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; }
} ;
🥂 206. 反转链表 [链表] [反转] (三指针)
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; }
} ;
🍻 快速排序
🥂 215. 数组中的第K个最大元素 [数组] [第K大元素] (三指针) (快速排序)
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 } ; }
} ;
🥂 912. 排序数组 [数组] [排序] (三指针) (快速排序)
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 } ; }
} ;
🍺 滑动窗口
🍻 子串
🥂 3. 无重复字符的最长子串 [字符串] [子串] (滑动窗口)
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; }
} ;
🍻 区间和
🥂 1423. 可获得的最大点数 [数组] > [区间外最大值] > [区间内最小值] > (定长滑动窗口)
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; }
} ;