一、哈希
1.两数之和
1. 两数之和
class Solution {
public :
vector< int > twoSum ( vector< int > & nums, int target) {
unordered_map< int , int > mp;
for ( int i = 0 ; i < nums. size ( ) ; i++ ) {
auto num = mp. find ( target - nums[ i] ) ;
if ( num != mp. end ( ) ) {
return { i, num -> second} ;
}
else {
mp[ nums[ i] ] = i;
}
}
return { - 1 , - 1 } ;
}
} ;
2.字母异位词分组
49. 字母异位词分组
class Solution {
public :
vector< vector< string>> groupAnagrams ( vector< string> & strs) {
vector< vector< string>> res;
if ( strs. size ( ) == 0 ) return res;
unordered_map< string, vector< string>> mp;
for ( auto t : strs) {
string str = t;
sort ( str. begin ( ) , str. end ( ) ) ;
mp[ str] . push_back ( t) ;
}
for ( auto it = mp. begin ( ) ; it != mp. end ( ) ; it ++ ) {
res. push_back ( it -> second) ;
}
return res;
}
} ;
3.最长连续序列
128. 最长连续序列
class Solution {
public :
int longestConsecutive ( vector< int > & nums) {
if ( nums. size ( ) == 0 ) return 0 ;
unordered_set< int > mp;
for ( const int & nun : nums) {
mp. insert ( num) ;
}
int res = 0 ;
for ( auto ch : mp) {
if ( ! mp. count ( ch - 1 ) ) {
int curNum = ch;
int curStreak = 1 ;
while ( mp. count ( curNum + 1 ) ) {
curNum += 1 ;
curStreak += 1 ;
}
res = max ( res, curStreak) ;
}
}
return res;
}
} ;
二、双指针
4. 移动零
283. 移动零
class Solution {
public :
void moveZeroes ( vector< int > & nums) {
if ( nums. size ( ) == 0 ) return ;
int slow = 0 ;
int fast = 0 ;
while ( fast < nums. size ( ) ) {
if ( nums[ fast] != 0 ) {
nums[ slow ++ ] = nums[ fast] ;
}
fast ++ ;
}
for ( int i = slow; i < nums. size ( ) ; i++ ) {
nums[ i] = 0 ;
}
}
} ;
5.盛最多水的容器
11. 盛最多水的容器
class Solution {
public :
int maxArea ( vector< int > & height) {
int i = 0 , j = height. size ( ) - 1 ;
int res = 0 ;
while ( i < j) {
res = height[ i] < height[ j] ?
max ( res, ( j - i) * height[ i ++ ] ) :
max ( res, ( j - i) * height[ j -- ] ) ;
}
return res;
}
} ;
6.三数之和
15. 三数之和
class Solution {
public :
vector< vector< int >> threeSum ( vector< int > & nums) {
vector< vector< int >> res;
if ( nums. size ( ) == 0 ) return res;
sort ( nums. begin ( ) , nums. end ( ) ) ;
if ( nums[ 0 ] > 0 ) return res;
for ( int k = 0 ; k < nums. size ( ) - 2 ; k ++ ) {
if ( k > 0 && nums[ k] == nums[ k - 1 ] ) continue ;
int i = k + 1 , j = nums. size ( ) - 1 ;
while ( i < j) {
int sum = nums[ k] + nums[ i] + nums[ j] ;
if ( sum < 0 ) {
while ( i < j && nums[ i] == nums[ ++ i] ) ;
}
else if ( sum > 0 ) {
while ( i < j && nums[ j] == nums[ -- j] ) ;
}
else {
res. push_back ( vector< int > { nums[ k] , nums[ i] , nums[ j] } ) ;
while ( i < j && nums[ i] == nums[ ++ i] ) ;
while ( i < j && nums[ j] == nums[ -- j] ) ;
}
}
}
return res;
}
} ;
7.接雨水
42. 接雨水
三、滑动窗口
8.无重复字符的最长子串
3. 无重复字符的最长子串
class Solution {
public :
int lengthOfLongestSubstring ( string s) {
unordered_map< char , int > windows;
int left = 0 , right = 0 ;
int res = 0 ;
int n = s. size ( ) ;
while ( right < n) {
char c = s[ right] ;
right ++ ;
windows[ c] ++ ;
while ( windows[ c] > 1 ) {
char d = s[ left] ;
left ++ ;
windows[ d] -- ;
}
res = max ( res, right - left) ;
}
return res;
}
} ;
9.找到字符串中所有字母异位词
438. 找到字符串中所有字母异位词
class Solution {
public :
vector< int > findAnagrams ( string s, string p) {
unordered_map< char , int > need, window;
for ( char c : p) need[ c] ++ ;
int left = 0 , right = 0 ;
int vaild = 0 ;
vector< int > res;
while ( right < s. size ( ) ) {
char c = s[ right] ;
right ++ ;
if ( need. count ( c) ) {
window[ c] ++ ;
if ( window[ c] == need[ c] ) {
vaild++ ;
}
}
while ( right - left >= p. size ( ) ) {
if ( vaild == need. size ( ) )
res. push_back ( left) ;
char d = s[ left] ;
left ++ ;
if ( need. count ( d) ) {
if ( window[ d] == need[ d] )
vaild-- ;
window[ d] -- ;
}
}
}
return res;
}
} ;
四、子串
10.和为 K 的子数组
560. 和为 K 的子数组
class Solution {
public :
int subarraySum ( vector< int > & nums, int k) {
unordered_map< int , int > mp;
mp[ 0 ] = 1 ;
int count = 0 , pre = 0 ;
for ( auto x : nums) {
pre += x;
if ( mp. find ( pre - k) != mp. end ( ) ) {
count += mp[ pre - k] ;
}
mp[ pre] ++ ;
}
return count;
}
} ;
11.滑动窗口最大值
239. 滑动窗口最大值
12.最小覆盖子串
76. 最小覆盖子串
class Solution {
public :
string minWindow ( string s, string t) {
unordered_map< char , int > need, windows;
for ( char c : t) need[ c] ++ ;
int left = 0 , right = 0 ;
int vaild = 0 ;
int start = 0 ;
int len = INT_MAX;
while ( right < s. size ( ) ) {
char c = s[ right] ;
right ++ ;
if ( need. count ( c) ) {
windows[ c] ++ ;
if ( windows[ c] == need[ c] ) {
vaild ++ ;
}
}
while ( vaild == need. size ( ) ) {
if ( right - left < len) {
start = left;
len = right - left;
}
char d = s[ left] ;
left ++ ;
if ( need. count ( d) ) {
if ( windows[ d] == need[ d] ) {
vaild-- ;
}
windows[ d] -- ;
}
}
}
return len == INT_MAX ? "" : s. substr ( start, len) ;
}
} ;
五、普通数组
13.最大子数组和
53. 最大子数组和
class Solution {
public :
int maxSubArray ( vector< int > & nums) {
if ( nums. size ( ) == 0 ) return - 1 ;
vector< int > dp ( nums. size ( ) , 0 ) ;
dp[ 0 ] = nums[ 0 ] ;
int result = dp[ 0 ] ;
for ( int i = 1 ; i < nums. size ( ) ; i++ ) {
dp[ i] = max ( dp[ i - 1 ] + nums[ i] , nums[ i] ) ;
if ( result < dp[ i] ) result = dp[ i] ;
}
return result;
}
} ;
14.合并区间
56. 合并区间
class Solution {
public :
vector< vector< int >> merge ( vector< vector< int >> & intervals) {
vector< vector< int >> res;
sort ( intervals. begin ( ) , intervals. end ( ) ) ;
if ( intervals. size ( ) == 0 ) return res;
for ( auto interval : intervals) {
if ( res. size ( ) == 0 || interval[ 0 ] > res. back ( ) [ 1 ] ) {
res. push_back ( interval) ;
continue ;
}
int start = res. back ( ) [ 0 ] ;
int end = max ( interval[ 1 ] , res. back ( ) [ 1 ] ) ;
res. back ( ) = { start, end} ;
}
return res;
}
} ;
15.轮转数组
189. 轮转数组
class Solution {
public :
void reverse ( vector< int > & nums, int start, int end) {
while ( start < end) {
swap ( nums[ start] , nums[ end] ) ;
start += 1 ;
end -= 1 ;
}
}
void rotate ( vector< int > & nums, int k) {
k %= nums. size ( ) ;
reverse ( nums, 0 , nums. size ( ) - 1 ) ;
reverse ( nums, 0 , k - 1 ) ;
reverse ( nums, k, nums. size ( ) - 1 ) ;
}
} ;
16.除自身以外数组的乘积
238. 除自身以外数组的乘积
class Solution {
public :
vector< int > productExceptSelf ( vector< int > & nums) {
int len = nums. size ( ) ;
if ( len == 0 ) return { } ;
vector< int > ansl ( len, 1 ) ;
vector< int > ansr ( len, 1 ) ;
for ( int i = 1 ; i < len; i++ ) {
ansl[ i] = ansl[ i - 1 ] * nums[ i - 1 ] ;
}
for ( int i = len - 2 ; i >= 0 ; i-- ) {
ansr[ i] = ansr[ i + 1 ] * nums[ i + 1 ] ;
}
for ( int i = 0 ; i < len; i++ ) {
ansl[ i] *= ansr[ i] ;
}
return ansl;
}
} ;
17.缺失的第一个正数
41. 缺失的第一个正数
class Solution {
public :
int firstMissingPositive ( vector< int > & nums) {
int n = nums. size ( ) ;
for ( int i = 0 ; i < n; i ++ ) {
if ( nums[ i] <= 0 ) {
nums[ i] = 0x3f3f3f3f ;
}
}
for ( int i = 0 ; i < n; i ++ ) {
int num = abs ( nums[ i] ) ;
if ( num <= n) {
nums[ num - 1 ] = - abs ( nums[ num - 1 ] ) ;
}
}
for ( int i = 0 ; i < n; i++ ) {
if ( nums[ i] > 0 ) {
return i + 1 ;
}
}
return n + 1 ;
}
} ;
六、矩阵
18.矩阵置零
73. 矩阵置零
class Solution {
public :
void setZeroes ( vector< vector< int >> & matrix) {
int n = matrix. size ( ) ;
int m = matrix[ 0 ] . size ( ) ;
bool FirstRowHasZero = false ;
bool FirstColHasZero = false ;
for ( int j = 0 ; j < m; ++ j) {
if ( matrix[ 0 ] [ j] == 0 ) {
FirstRowHasZero = true ;
break ;
}
}
for ( int i = 0 ; i < n; ++ i) {
if ( matrix[ i] [ 0 ] == 0 ) {
FirstColHasZero = true ;
break ;
}
}
for ( int i = 1 ; i< n; ++ i)
{
for ( int j = 1 ; j< m; ++ j)
{
if ( matrix[ i] [ j] == 0 ) {
matrix[ 0 ] [ j] = 0 ;
matrix[ i] [ 0 ] = 0 ;
}
}
}
for ( int i = 1 ; i< n; ++ i)
{
for ( int j = 1 ; j< m; ++ j)
{
if ( matrix[ 0 ] [ j] == 0 || matrix[ i] [ 0 ] == 0 )
{
matrix[ i] [ j] = 0 ;
}
}
}
if ( FirstRowHasZero) {
for ( int j = 0 ; j < m; ++ j) {
matrix[ 0 ] [ j] = 0 ;
}
}
if ( FirstColHasZero) {
for ( int i = 0 ; i < n; ++ i) {
matrix[ i] [ 0 ] = 0 ;
}
}
}
} ;
19.螺旋矩阵
54. 螺旋矩阵
class Solution {
public :
vector< int > spiralOrder ( vector< vector< int >> & matrix) {
if ( matrix. empty ( ) ) return { } ;
vector< int > res;
int l = 0 , r = matrix[ 0 ] . size ( ) - 1 ;
int t = 0 , b = matrix. size ( ) - 1 ;
while ( true ) {
for ( int i = l; i <= r; i++ ) res. push_back ( matrix[ t] [ i] ) ;
if ( ++ t > b) break ;
for ( int i = t; i <= b; i++ ) res. push_back ( matrix[ i] [ r] ) ;
if ( l > -- r) break ;
for ( int i = r; i >= l; i-- ) res. push_back ( matrix[ b] [ i] ) ;
if ( t > -- b) break ;
for ( int i = b; i >= t; i-- ) res. push_back ( matrix[ i] [ l] ) ;
if ( ++ l > r) break ;
}
return res;
}
} ;
20. 旋转图像
48. 旋转图像
class Solution {
public :
void rotate ( vector< vector< int >> & matrix) {
int n = matrix. size ( ) ;
for ( int i = 0 ; i < n / 2 ; i ++ ) {
for ( int j = 0 ; j < ( n + 1 ) / 2 ; j ++ ) {
int tmp = matrix[ i] [ j] ;
matrix[ i] [ j] = matrix[ n - 1 - j] [ i] ;
matrix[ n - 1 - j] [ i] = matrix[ n - 1 - i] [ n - 1 - j] ;
matrix[ n - 1 - i] [ n - 1 - j] = matrix[ j] [ n - 1 - i] ;
matrix[ j] [ n - 1 - i] = tmp;
}
}
}
} ;
21. 搜索二维矩阵 II
240. 搜索二维矩阵 II
class Solution {
public :
bool searchMatrix ( vector< vector< int >> & matrix, int target) {
int m = matrix. size ( ) ;
int n = matrix[ 0 ] . size ( ) ;
int x = 0 , y = n - 1 ;
while ( x < m && y >= 0 ) {
if ( matrix[ x] [ y] == target) {
return true ;
}
if ( matrix[ x] [ y] > target) {
y-- ;
}
else {
x++ ;
}
}
return false ;
}
} ;
七、链表
22. 相交链表
160. 相交链表
class Solution {
public :
ListNode * getIntersectionNode ( ListNode * headA, ListNode * headB) {
if ( headA == nullptr || headB == nullptr ) {
return nullptr ;
}
ListNode* cur1 = headA;
ListNode* cur2 = headB;
while ( cur1 != cur2) {
if ( cur1 == nullptr ) cur1 = headB;
else cur1 = cur1 -> next;
if ( cur2 == nullptr ) cur2 = headA;
else cur2 = cur2 -> next;
}
return cur1;
}
} ;
23. 反转链表
206. 反转链表
class Solution {
public :
ListNode* reverseList ( ListNode* head) {
if ( head == nullptr ) return nullptr ;
ListNode* pre= nullptr ;
ListNode* cur = head;
ListNode* temp = nullptr ;
while ( cur) {
temp = cur -> next;
cur -> next = pre;
pre = cur;
cur = temp;
}
return pre;
}
} ;
24. 反转链表
234. 回文链表
class Solution {
public :
bool isPalindrome ( ListNode* head) {
if ( head == nullptr ) return false ;
ListNode* endNode = findNode ( head) ;
ListNode* newHead = reverseNode ( endNode -> next) ;
ListNode* p1 = head;
ListNode* p2 = newHead;
bool result = true ;
while ( result && p2 != nullptr ) {
if ( p1 -> val != p2 -> val) {
result = false ;
}
p1 = p1 -> next;
p2 = p2 -> next;
}
endNode -> next = reverseNode ( newHead) ;
return result;
}
ListNode* findNode ( ListNode* head) {
ListNode* fast = head -> next;
ListNode* slow = head;
while ( fast && fast -> next) {
fast = fast -> next -> next;
slow = slow -> next;
}
return slow;
}
ListNode* reverseNode ( ListNode* head) {
ListNode* cur = head;
ListNode* temp = nullptr ;
ListNode* pre = nullptr ;
while ( cur) {
temp = cur -> next;
cur -> next = pre;
pre = cur;
cur = temp;
}
return pre;
}
} ;
25. 环形链表
141. 环形链表
class Solution {
public :
bool hasCycle ( ListNode * head) {
if ( head == nullptr || head -> next == nullptr )
return false ;
ListNode* slow = head;
ListNode* fast = head -> next;
while ( fast && fast -> next) {
fast = fast -> next -> next;
slow = slow -> next;
if ( fast == slow)
return true ;
}
return false ;
}
} ;
26. 环形链表 II
142. 环形链表 II
class Solution {
public :
ListNode * detectCycle ( ListNode * head) {
if ( head == nullptr || head -> next == nullptr ) return nullptr ;
ListNode* fast = head;
ListNode* slow = head;
while ( fast && fast -> next) {
fast = fast -> next -> next;
slow = slow -> next;
if ( fast == slow) {
ListNode* index1 = slow;
ListNode* index2 = head;
while ( index1 != index2) {
index1 = index1 -> next;
index2 = index2 -> next;
}
return index2;
}
}
return nullptr ;
}
} ;
27. 合并两个有序链表
21. 合并两个有序链表
class Solution {
public :
ListNode* mergeTwoLists ( ListNode* list1, ListNode* list2) {
if ( list1 == nullptr ) return list2;
if ( list2 == nullptr ) return list1;
ListNode* dummy = new ListNode ( - 1 ) ;
ListNode* cur = dummy;
ListNode* cur1 = list1;
ListNode* cur2 = list2;
while ( cur1 && cur2) {
if ( cur1 -> val > cur2 -> val) {
cur -> next = cur2;
cur2 = cur2 -> next;
}
else {
cur -> next = cur1;
cur1 = cur1 -> next;
}
cur = cur -> next;
}
if ( cur1) cur -> next = cur1;
if ( cur2) cur -> next = cur2;
return dummy -> next;
}
} ;
28. 两数相加
2. 两数相加
class Solution {
public :
ListNode* addTwoNumbers ( ListNode* l1, ListNode* l2) {
if ( l1 == nullptr ) return l2;
if ( l2 == nullptr ) return l1;
ListNode* dummy = new ListNode ( - 1 ) ;
ListNode* cur1 = l1;
ListNode* cur2 = l2;
ListNode* cur = dummy;
int t = 0 ;
while ( cur1 || cur2 || t) {
if ( cur1) {
t += cur1 -> val;
cur1 = cur1 -> next;
}
if ( cur2) {
t += cur2 -> val;
cur2 = cur2 -> next;
}
cur -> next = new ListNode ( t % 10 ) ;
t = t / 10 ;
cur = cur -> next;
}
return dummy -> next;
}
} ;
29. 删除链表的倒数第 N 个结点
19. 删除链表的倒数第 N 个结点
class Solution {
public :
ListNode* removeNthFromEnd ( ListNode* head, int n) {
if ( head == nullptr || n == 0 ) return nullptr ;
ListNode* dummy = new ListNode ( - 1 ) ;
dummy -> next = head;
ListNode* x = find ( dummy, n + 1 ) ;
x -> next = x -> next -> next;
return dummy -> next;
}
ListNode* find ( ListNode* head, int k) {
ListNode* slow = head;
ListNode* fast = head;
while ( fast && k -- ) {
fast = fast -> next;
}
while ( fast) {
fast = fast -> next;
slow = slow -> next;
}
return slow;
}
} ;