LeetCode 热题 HOT 100
Posted 行码阁119
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 热题 HOT 100相关的知识,希望对你有一定的参考价值。
申明:以下所有内容均来自力扣
此博客就是总结了部分作者觉得好的题,难得题,需要品味的题,也是需要背诵的题。
此题没有明确说明,就是作者自己写的代码。
大家看了题没思路的话,自己点开,看题解。
本博客主要是方便复习和查看
4. 寻找两个正序数组的中位数https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
给定两个大小分别为 m和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
利用两个数组逐渐递增的性质,l指向nums1, l2指向nums2,判断两者的大小,一次写入数组record,当找到中间元素,跳出 。
class Solution
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
vector<int> record(nums1.size() + nums2.size(), 0);
int n = nums1.size();
int m = nums2.size();
int t = (n + m) / 2;
int t1 = (n + m) % 2;
int l = 0;
int r = 0;
int j = 0;
while(l + r <= t)
if(l < n && r < m && nums1[l] >= nums2[r])
record[j++] = nums2[r];
r++;
else if(l < n && r < m && nums1[l] < nums2[r])
record[j++] = nums1[l];
l++;
else if(l >= n && r < m )
record[j++] = nums2[r];
r++;
else if(l < n && r >= m )
record[j++] = nums1[l];
l++;
else break;
if(t1 == 1)
return record[l + r - 1];
return double(record[r + l - 2] + record[r + l - 1]) / 2 ;
;
class Solution
public:
int getKthElement(const vector<int>& nums1, const vector<int>& nums2, int k)
/* 主要思路:要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较
* 这里的 "/" 表示整除
* nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个
* nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个
* 取 pivot = min(pivot1, pivot2),两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个
* 这样 pivot 本身最大也只能是第 k-1 小的元素
* 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums1 数组
* 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums2 数组
* 由于我们 "删除" 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除的数的个数
*/
int m = nums1.size();
int n = nums2.size();
int index1 = 0, index2 = 0;
while (true)
// 边界情况
if (index1 == m)
return nums2[index2 + k - 1];
if (index2 == n)
return nums1[index1 + k - 1];
if (k == 1)
return min(nums1[index1], nums2[index2]);
// 正常情况
int newIndex1 = min(index1 + k / 2 - 1, m - 1);
int newIndex2 = min(index2 + k / 2 - 1, n - 1);
int pivot1 = nums1[newIndex1];
int pivot2 = nums2[newIndex2];
if (pivot1 <= pivot2)
k -= newIndex1 - index1 + 1;
index1 = newIndex1 + 1;
else
k -= newIndex2 - index2 + 1;
index2 = newIndex2 + 1;
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
int totalLength = nums1.size() + nums2.size();
if (totalLength % 2 == 1)
return getKthElement(nums1, nums2, (totalLength + 1) / 2);
else
return (getKthElement(nums1, nums2, totalLength / 2) + getKthElement(nums1, nums2, totalLength / 2 + 1)) / 2.0;
;
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xun-zhao-liang-ge-you-xu-shu-zu-de-zhong-wei-s-114/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
10. 正则表达式匹配https://leetcode-cn.com/problems/regular-expression-matching/
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
难 题没读懂
示例 1:
输入:s = "aa", p = "a"
输出:false
解释:"a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:s = "aa", p = "a*"
输出:true
解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:
输入:s = "ab", p = ".*"
输出:true
解释:".*" 表示可匹配零个或多个('*')任意字符('.')。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/regular-expression-matching
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这里是官方代码,解释请去官方
class Solution
public:
bool isMatch(string s, string p)
int m = s.size();
int n = p.size();
auto matches = [&](int i, int j)
if (i == 0)
return false;
if (p[j - 1] == '.')
return true;
return s[i - 1] == p[j - 1];
;
vector<vector<int>> f(m + 1, vector<int>(n + 1));
f[0][0] = true;
for (int i = 0; i <= m; ++i)
for (int j = 1; j <= n; ++j)
if (p[j - 1] == '*')
f[i][j] |= f[i][j - 2];
if (matches(i, j - 1))
f[i][j] |= f[i - 1][j];
else
if (matches(i, j))
f[i][j] |= f[i - 1][j - 1];
return f[m][n];
;
23. 合并K个升序链表https://leetcode-cn.com/problems/merge-k-sorted-lists/
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入:lists = []
输出:[]
示例 3:
输入:lists = [[]]
输出:[]
class Solution
public:
class mycompare
public:
bool operator()(const ListNode* A, const ListNode *B)
return A->val > B->val;
;
ListNode* mergeKLists(vector<ListNode*>& lists)
//创建一个小顶堆
priority_queue<ListNode*, vector<ListNode*>, mycompare> que;
//将数据压入优先队列中
for(int i = 0; i < lists.size(); i++)
auto t = lists[i];
while(t != NULL)
que.push(t);
t = t->next;
//申明一个虚拟头结点
//这里一定要注意链表的结尾要赋予空
ListNode* head = new ListNode(0);
ListNode* cur = head;
while(!que.empty())
cur->next = que.top();
cur = cur->next;
cur->next = NULL;
que.pop();
return head->next;
;
155. 最小栈https://leetcode-cn.com/problems/min-stack/
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
class MinStack
public:
stack<int> q;
stack<int> p;
MinStack()
p.push(INT_MAX);
void push(int val)
q.push(val);
if(val < p.top())
p.push(val);
else
p.push(p.top());
void pop()
q.pop();
p.pop();
int top()
return q.top();
int getMin()
return p.top();
;
234. 回文链表https://leetcode-cn.com/problems/palindrome-linked-list/
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
进阶:你能否用 O(n)
时间复杂度和 O(1)
空间复杂度解决此题?
class Solution
public:
bool isPalindrome(ListNode* head)
int n = 0;
ListNode* cur = head;
while(cur)
n++;
cur = cur->next;
cur = head;
ListNode* hummy = new ListNode(0);
int temp = n / 2;
while(temp > 0)
cur = cur->next;
temp--;
ListNode* pre = NULL;
while(cur)
ListNode* t = cur->next;
cur->next = pre;
pre = cur;
cur = t;
cur = head;
ListNode* op = pre;
bool t = true;
while(cur && pre)
if(cur->val != pre->val)
t = false;
break;
cur = cur->next;
pre = pre->next;
return t;
;
448. 找到所有数组中消失的数字https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/
给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。
示例 1:
输入:nums = [4,3,2,7,8,2,3,1]
输出:[5,6]
示例 2:
输入:nums = [1,1]
输出:[2]
进阶:你能在不使用额外空间且时间复杂度为 O(n)
的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。
class Solution
public:
vector<int> findDisappearedNumbers(vector<int>& nums)
vector<int> result;
int n = nums.size();
for(int num : nums)
int x = (num - 1) % n;
nums[x] = nums[x] + n;
for(int i = 0; i < nums.size(); i++)
if(nums[i] <= n)
result.push_back(i + 1);
return result;
;
543. 二叉树的直径https://leetcode-cn.com/problems/diameter-of-binary-tree/
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
示例 :
给定二叉树
1
/ \\
2 3
/ \\
4 5
返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
class Solution
public:
int ans = 0;
int recur(TreeNode* root)
if(root == NULL)
return 0;
int l = recur(root->left);
int r = recur(root->right);
ans = max(ans, l + r);
return max(l, r) + 1;
int diameterOfBinaryTree(TreeNode* root)
recur(root);
return ans;
;
以上是关于LeetCode 热题 HOT 100的主要内容,如果未能解决你的问题,请参考以下文章
#yyds干货盘点# LeetCode 热题 HOT 100:子集