1. 两数之和(为目标值) 3min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vector<int> twoSum(vector<int>& nums, int target)
{
umordered_map<int, int> hashtable;
/* xiaoguo */

for(int i = 0; i < nums.size(); i++)
{
auto it = hashtable.find(target - nums[i]);
if(it != hashtable.end())
return {it->second, i};
hashtable[nums[i]] = i;
}
return {};
}

2. 两数相加(链表形式给出,返回同样格式的链表) 4min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2)
{
ListNode* head = nullptr;
ListNode* tail = nullptr;
int carry = 0;
while(l1 || l2)
{
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 + carry;
if(!head)
{
head = tail = new ListNode(sum % 10);
}
else
{
tail->next = new ListNode(sum % 10);
tail = tail->next;
}
carry = sum / 10;
if(l1)
l1 = l1->next;
if(l2)
l2 = l2->next;
}
if(carry)
{
tail->next = new ListNode(carry);
}
return head;
}

3. 无重复字符的最长字串 2min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int lengthOfLongestSubstring(string s)
{
unordered_set<char> st;
int n = s.size();
int right = 0, ret = 0;
for(int left = 0; left < n; left++)
{
if(left != 0)
{
st.erase(s[left - 1]);
}
while(right < n && !st.count(s[right]))
{
st.insert(s[right]);
right++;
}
ret = max(ret, right - left);
}
return ret;
}

15. 三数之和(等于0) 9min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
vector<vector<int>> threeSum(vector<int>& nums)
{
sort(nums.begin(), nums.end());
vector<vector<int>> ret;
int n = nums.size();
if(n >= 3 && nums[n - 1] + nums[n - 2] + nums[n - 3] < 0)
return ret;
for(int first = 0; first < n - 2; first++)
{
if(nums[first] + nums[first + 1] + nums[first + 2] > 0)
break;
if(first > 0 && nums[first] == nums[first - 1])
continue;
int target = -nums[first];
int third = n - 1;
for(int second = first + 1; second < n - 1; second++)
{
if(second > first + 1 && nums[second] == nums[second - 1])
continue;
while(second < third && nums[second] + nums[third] > target)
--third;
if(second == third)
break;
if(nums[second] + nums[third] == target)
ret.push_back({nums[first], nums[second], nums[third]});
}
}
return ret;
}

84. 柱状图中的最大矩形 8min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int largestRectangleArea(vector<int>& heights)
{
int ret = 0;
int n = heights.size();
vector<int> left(n), right(n, n);
stack<int> monoStack;
for(int i = 0; i < n; i++)
{
while(!monoStack.empty() && heights[monoStack.top()] >= heights[i])
{
right[monoStack.top()] = i;
monoStack.pop();
}
left[i] = monoStack.empty() ? -1 : monoStack.top();
monoStack.push(i);
}
for(int i = 0; i < n; i++)
{
ret = max(ret, (right[i] - left[i] - 1) * heights[i]);
}
return ret;
}

85. 最大矩形 15min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int lagestRectangleArea(vector<int>& heights)
{
int ret = 0;
int n = heights.size();
vector<int> left(n), right(n, n);
stack<int> monoStack;
for(int i = 0; i < n; i++)
{
while(!monoStack.empty() && heights[monoStack.top()] >= heights[i])
{
right[monoStack.top()] = i;
monoStack.pop();
}
left[i] = monoStack.empty() ? -1 : monoStack.top();
monoStack.push(i);
}
for(int i = 0; i < n; i++)
{
ret = max(ret, (right[i] - left[i] - ) * heights[i]);
}
return ret;
}
int maximalRectangle(vector<vector<char>>& matrix)
{
int ret = 0;
int m = matrix.size();
if(m == 0)
return 0;
int n = matrix[0].size();
vector<int> dp (n, 0);
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
dp[j] = matrix[i][j] == '0' ? 0 : dp[j] + 1;
}
ret = max(ret, largestRectangleArea(dp));
}
return ret;
}

94. 二叉树的中序遍历

递归
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void inorder(TreeNode* root, vector<int>& ret)
{
if(!root)
return;
inorder(root->left, ret);
ret.push_back(root->val);
inorder(root->right, ret);
}
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> ret;
inorder(root, ret);
return ret;
}
非递归(栈)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> ret;
stack<TreeNode*> stk;
while(root || !stk.empty())
{
while(root)
{
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
ret.push_back(root->val);
root = root->right;
}
return ret;
}
Morris
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> ret;
TreeNode* predecessor = nullptr;
while(root)
{
if(root->left != nullptr)
{
predecessor = root->left;
while(predecessor->right != nullptr && predecessor->right != root)
{
predecessor = predecessor->right;
}
if(predecessor->right == nullptr)
{
predecessor->right = root;
root = root->left;
}
else
{
ret.push_back(root->val);
predecessor->right = nullptr;
root = root->right;
}
}
else
{
ret.push_back(root->val);
root = root->right;
}
}
return res;
}

96. (n个点能组成的)不同的二叉搜索树 1min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int numTrees(int n)
{
vector<int> dp(n + 1, 0);
dp[0] = 1;
dp[1] = 1;
for(int m = 2; m <= n; m++)
{
for(int i = 1; i <= m; i++)
{
dp[m] += dp[i - 1] * dp[m - i];
}
}
return dp[n];
}

98. 验证(一棵树是否为)二叉搜索树 3min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool isValidBST(TreeNode* root)
{
long long inorder = (long long)INT_MIN - 1;
stack<TreeNode*> stk;
while(root || !stk.empty())
{
while(root)
{
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
if(root->val <= inorder)
{
return false;
}
inorder = root->val;
root = root->right;
}
return true;
}

102. 二叉树的层序遍历(按层次打印到二维数组中) 6min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
vector<vector<int>> levelOrder(TreeNode* root)
{
vector<vector<int>> ret;
if(!root)
{
return ret;
}
queue<TreeNode*> que;
que.push(root);
while(!que.empty())
{
int n = que.size();
vector<int> temp;
for(int i = 0; i < n; i++)
{
auto node = que.front();
que.pop();
temp.push_back(node->val);
if(node->left)
que.push(node->left);
if(node->right)
que.push(node->right);
}
ret.push_back(temp);
}
return ret;
}

114. 二叉树(原地)展开为链表(顺着右子节点连) 3min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void flatten(TreeNode* root)
{
TreeNode* cur = root;
while(cur)
{
if(cur->left)
{
auto next = cur->left;
auto predecessor = next;
while(predecessor->right)
predecessor = predecessor->right;
predecessor->right = cur->right;
cur->left = nullptr;
cur->right = next;
}
cur = cur->right;
}
}

121. 买卖股票的最佳时机 1min

1
2
3
4
5
6
7
8
9
10
int maxProfit(vector<int>& prices)
{
int minprice = 1e9, maxprofit = 0;
for(int price : prices)
{
minprice = min(price, minprice);
maxprofit = max(maxprofit, price - minprice);
}
return maxprofit;
}

124. (从任意点起的)二叉树中的最大路径和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int maxGain(TreeNode* root, int& maxSum)
{
if(root)
return 0;
int left = max(maxGain(root->left), 0);
int right = max(maxGain(root->right), 0);
int curMaxSum = root->val + left + right;
maxSum = max(maxSum, curMaxSum);
return root->val + max(left, right);
}
int maxPathSum(TreeNode* root)
{
int maxSum = INT_MIN;
maxGain(root, maxSum);
return maxSum;
}

128. (无序数组中能找出的)最长连续序列(需要O(n)时间复杂度)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int longestConsecutive(vector<int>& nums)
{
unordered_set<int> st;
int longestSeq = 0;
for(int num : nums)
st.insert(num);
for(int s : st)
{
if(!st.count(s - 1))
{
int curSeq = 1;
int curNum = s;
while(st.count(curNum + 1))
{
curSeq++;
curNum++;
}
longestSeq = max(longestSeq, curSeq);
}
}
return longestSeq;
}

136. (在其余数字都出现两次的数组中找)只出现一次的数字(要求线性时间,不使用额外空间)

1
2
3
4
5
6
7
int singleNum(vector<int>& nums)
{
int ret = 0;
for(int num : nums)
ret ^= num;
return ret;
}

139. 单词(是否可以)拆分(成字符串数组中的元素) 4min

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool wordBreak(string s, vector<string>& wordDict)
{
unordered_set<string> st;
for(string word : wordDict)
st.insert(word);
vector<bool> dp(s.size() + 1);
dp[0] = true;
for(int i = 1; i <= s.size();i++)
{
for(int j = 0; j < i; j++)
if(dp[j] && st.find(s.substr(j, i - j)) != st.end())
{
dp[i] = true;
break;
}
}
return dp[s.size()];
}

146. LRU缓存机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
struct DLinkedNode
{

int key, value;
DLinkedNode* prev;
DLinkedNode* next;
DLinkedNode() : key(0), value(0), prev(nullptr), next(nullptr){};
DLinkedNode(int _key, int _value) : key(_key), value(_value), prev(nullptr), next(nullptr){};
};
class LRUCache
{

private:
unordered_map<int, DLinkedNode*> cache;
int size, capacity;
DLinkedNode* head;
DLinkedNode* tail;
public:
LRUCache(int _capacity) : size(0), capacity(_capacity)
{
head = new DLinkedNode();
tail = new DLinkedNode();
head->next = tail;
tail->prev = head;
}
int get(int key)
{
if(!cache.count(key))
{
return -1;
}
DLinkedNode* node = cache[key];
moveToHead(node);
return node->value;
}
void put(int key, int value)
{
if(!cache.count(key))
{
DLinkedNode* node = new DLinkedNode(key, value);
cache[key] = node;
addToHead(node);
size++;
if(size > capacity)
{
DLinkedNode* remove = tail->prev;
cache.erase(remove->key);
removeTail();
size--;
delete remove;
}
}
else
{
DLinkedNode* node = cache[key];
node->value = value;
moveToHead(node);
}
}
void addToHead(DLinkedNode* node)
{
node->prev = head;
node->next = head->next;
head->next->prev = node;
head->next = node;
}
void removeNode(DLinkedNode* node)
{
node->next->prev = node->prev;
node->prev->next = node->next;
}
void moveToHead(DLinkedNode* node)
{
removeNode(node);
addToHead(node);
}
DLinkedNode* removeTail()
{
DLinkedNode* node = tail->prev;
removeNode(node);
return node;
}
};

148. 排序链表(要求时间复杂度O(nlogn),空间复杂度O(1))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
ListNode* sortList(ListNode* head)
{
if(head == nullptr)
{
return head;
}
ListNode* node = head;
int length = 0;
while(node != nullptr)
{
length++;
node = node->next;
}
ListNode* dummyHead = new ListNode(0, head);
for(int subLength = 1; subLength < length; subLength <<= 1)
{
ListNode* prev = dummyHead;
ListNode* curr = dummyHead->next;
while(curr != nullptr)
{
ListNode* head1 = curr;
for(int i = 1; i < subLength && curr->next != nullptr; i++)
{
curr = curr->next;
}
ListNode* head2 = curr->next;
curr->next = nullptr;
curr = head2;
for(int i = 1; i < subLength && curr != nullptr && curr->next != nullptr; i++)
{
curr = curr->next;
}
ListNode* next = nullptr;
if(curr != nullptr)
{
next = curr->next;
curr->next = nullptr;
}
//curr = next;
ListNode* merged = merge(head1, head2);
prev->next = merged;
while(prev->next != nullptr)
{
prev = prev->next;
}
curr = next;
}
}
return dummyHead->next;
}
ListNode* merge(ListNode* head1, ListNode* head2)
{
ListNode* dummyHead = new ListNode(0);
ListNode* temp = dummyHead;
ListNode* temp1 = head1;
ListNode* temp2 = head2;
while(temp1 != nullptr && temp2 != nullptr)
{
if(temp1->val <= temp2->val)
{
temp->next = temp1;
temp1 = temp1->next;
}
else
{
temp->next = temp2;
temp2 = temp2->next;
}
temp = temp->next;
}
if(temp1 != nullptr)
{
temp->next = temp1;
}
else if(temp2 != nullptr)
{
temp->next = temp2;
}
return dummyHead->next;
}

152. 乘积最大子数组

1
2
3
4
5
6
7
8
9
10
11
12
13
int maxProduct(vector<int>& nums)
{
int maxF = nums[0], minF = nums[0];
int ans = nums[0];
for(int i = 1; i < nums.size(); i++)
{
int mx = maxF, mn = minF;
maxF = max(mx * nums[i], max(mn * nums[i], nums[i]));
minF = min(mx * nums[i], min(mn * nums[i], nums[i]));
ans = max(maxF, ans);
}
return ans;
}

155. 最小栈(保证能常数时间内返回最小值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class MinStack
{

public:
stack<int> xStack;
stack<int> mStack;
MinStack()
{
mStack.push(INT_MIN);
}
void push(int x)
{
xStack.push(x);
mStack.push(min(x, mStack.pop()));
}
void pop()
{
xStack.pop();
mStack.pop();
}
int top()
{
return xStack.top();
}
int getMin()
{
return mStack.top();
}
};

198. 打家劫舍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int rob(vector<int>& nums)
{
if(nums.empty())
return 0;
int n = nums.size();
if(n == 1)
return nums[0];
vector<int> dp(n, 0);
dp[0] = nums[0];
dp[1] = max(nums[0], nums[1]);
for(int i = 2; i < n; i++)
{
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[n - 1];
}

200. 岛屿数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class UnionFind
{

private:
vector<int> parent;
vector<int> rank;
int count = 0;
public:
UnionFind(vector<vector<char>>& grid)
{
int m = grid.size();
int n = grid[0].size();
for(int r = 0; r < m; r++)
{
for(int c = 0; c < n; c++)
{
if(grid[r][c] == '1')
{
parent.push_back(r * n + c);
count++;
}
else
{
parent.push_back(-1);
}
rank.push_back(0);
}
}
}
int find(int i)
{
if(parent[i] != i)
parent[i] = find(parent[i]);
return parent[i];
}
void unite(int x, int y)
{
int rootx = find(x);
int rooty = find(y);
if(rootx != rooty)
{
if(rank[rootx] < rank[rooty])
{
swap(rootx, rooty);
}
if(rank[rootx] == rank[rooty])
{
rank[rootx] += 1;
}
parent[rooty] = rootx;
count--;
}
}
int getCount()
{
return count;
}
};
class Solution
{

public:
int numIslands(vector<vector<char>>& grid)
{
int nr = grid.size();
int nc = grid[0].size();
UnionFind uf(grid);
for(int r = 0; r < nr; r++)
{
for(int c = 0; c < nc; c++)
{
if(grid[r][c] == '1')
{
grid[r][c] = '0';
if(r - 1 >= 0 && grid[r - 1][c] == '1') uf.unite(r * nc + c, (r - 1) * nc + c);
if(r + 1 < nr && grid[r + 1][c] == '1') uf.unite(r * nc + c, (r + 1) * nc + c);
if(c - 1 >= 0 && grid[r][c - 1] == '1') uf.unite(r * nc + c, r * nc + c - 1);
if(c + 1 < nc && grid[r][c + 1] == '1') uf.unite(r * nc + c, r * nc + c + 1);
}
}
}
return uf.getCount();
}
};

206. 翻转链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 递归
ListNode* reverseList(ListNode* head)
{
if(head == nullptr || head->next == nullptr)
{
return head;
}
ListNode* ret = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return ret;
}
// 双指针迭代
ListNode* reverseList(ListNode* head)
{
ListNode* pre = head;
ListNode* cur = nullptr;
while(pre != nullptr)
{
ListNode* p = pre->next;
pre->next = cur;
cur = pre;
pre = p;
}
return cur;
}

208. 实现Trie(前缀树)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Trie
{

private:
bool isEnd;
Trie* next[26];
public:
Trie()
{
isEnd = false;
memset(next, 0, sizeof(next));
}
void insert(string word)
{
Trie* node = this;
for(char c : word)
{
if(node->next[c - 'a'] == nullptr)
{
node->next[c - 'a'] = new Trie();
}
node = node->next[c - 'a'];
}
node->isEnd = true;
}
bool search(string word)
{
Trie* node = this;
for(char c : word)
{
if(node->next[c - 'a'] == nullptr)
{
return false;
}
node = node->next[c - 'a'];
}
return node->isEnd;
}
bool startsWith(string prefix)
{
Trie* node = this;
for(char c : prefix)
{
if(node->next[c - 'a'] == nullptr)
{
return false;
}
node = node->next[c - 'a'];
}
return true;
}
};

739. 每日温度(每天找下一个比今天更高的温度)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
vector<int> dailyTemperature(vector<int>& T)
{
int n = T.size();
vector<int> ret(n);
stack<int> stk;
for(int i = 0; i < n; i++)
{
while(!stk.empty() && T[i] > T[stk.top()])
{
int prevIndex = stk.top();
ret[prevIndex] = i - prevIndex;
stk.pop();
}
stk.push(i);
}
return ret;
}