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的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 热题 HOT 100

#yyds干货盘点# LeetCode 热题 HOT 100:子集

leetcode热题Hot100——LRU缓存

#yyds干货盘点# LeetCode 热题 HOT 100:全排列

leetcode热题Hot100——LRU缓存

#yyds干货盘点# LeetCode 热题 HOT 100:最长有效括号