【LeetCode】 热题 HOT 100代码汇总

记录LeetCode 热题 HOT 100 代码

1. 两数之和

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> hash;
        for(int i = 0; i < nums.size(); i ++ )
        {
            int r = target - nums[i];
            if(hash.count(r)) return {hash[r], i};
            hash[nums[i]] = i;
        }
        return {};
    }
};

2. 两数相加

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        auto dummy = new ListNode(-1), cur = dummy;
        int t = 0;
        while(l1 || l2 || t)
        {
            if(l1) t += l1->val, l1 = l1->next;
            if(l2) t += l2->val, l2 = l2->next;
            cur = cur->next = new ListNode(t % 10);
            t /= 10;
        }
        return dummy->next;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/1437840/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3. 无重复字符的最长子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char, int> hash;
        int res = 0;
        for(int i = 0, j = 0; i < s.size(); i ++ )
        {
            hash[s[i]] ++ ;
            while(hash[s[i]] > 1) hash[s[j ++ ]] -- ;
            res = max(res, i - j + 1);
        }
        return res;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/1938829/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4. 寻找两个正序数组的中位数

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int tot = nums1.size() + nums2.size();
        if(tot % 2 == 0)
        {
            int left = find(nums1, 0, nums2, 0, tot / 2);
            int right = find(nums1, 0, nums2, 0, tot / 2 + 1);
            return (left + right) / 2.0;
        }
        else
            return find(nums1, 0, nums2, 0, tot / 2 + 1);
    }

    int find(vector<int>& nums1, int i, vector<int>& nums2, int j, int k)
    {
        if(nums1.size() - i > nums2.size() - j) return find(nums2, j, nums1, i, k);
        if(k == 1)
        {
            if(nums1.size() == i)
                return nums2[j];
            else
                return min(nums1[i], nums2[j]);
        }
        if(nums1.size() == i) return nums2[j + k - 1];
        int si = min((int)nums1.size(), i + k / 2), sj = j + k - k / 2;
        if(nums1[si - 1] > nums2[sj - 1]) return find(nums1, i, nums2, sj, k - (sj - j));
        else return find(nums1, si, nums2, j, k - (si - i));
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/2005352/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

5. 最长回文子串

class Solution {
public:
    string longestPalindrome(string s) {
        string res;
        for(int i = 0; i < s.size(); i ++ )
        {
            //枚举字符串长度是奇数的情况
            int l = i - 1, r = i + 1;
            while(l >= 0 && r < s.size() && s[l] == s[r]) l --, r ++ ;
            if(res.size() < r - l - 1) res = s.substr(l + 1, r - l - 1);

            //枚举字符串长度是偶数的情况
            l = i, r = i + 1;
            while(l >= 0 && r < s.size() && s[l] == s[r]) l --, r ++ ;
            if(res.size() < r - l - 1) res = s.substr(l + 1, r - l - 1);
        }
        return res;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/2012413/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

10. 正则表达式匹配

class Solution {
public:
    bool isMatch(string s, string p) {
        int n = s.size(), m = p.size();
        s = ' ' + s, p = ' ' + p;
        vector<vector<bool>> f(n + 1, vector<bool>(m + 1));

        f[0][0] = true;
        for(int i = 0; i <= n; i ++ )
            for(int j = 1; j <= m; j ++ )
            {
                if(j + 1 <= m && p[j + 1] == '*') continue;
                if(i && p[j] != '*')
                {
                    f[i][j] = f[i - 1][j - 1] && (s[i] == p[j] || p[j] == '.');
                }
                else if(p[j] == '*')
                {
                    f[i][j] = f[i][j - 2] || i && f[i - 1][j] && (s[i] == p[j - 1] || p[j - 1] == '.');
                }
            }
        return f[n][m];
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/2033105/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

11. 盛最多水的容器

正解是单调栈,巧解为双指针

双指针做法:

class Solution {
public:
    int maxArea(vector<int>& height) {
        int res = 0;
        for(int i = 0, j = height.size() - 1; i < j;)
        {
            res = max(res, min(height[i], height[j]) * (j - i));
            if(height[i] > height[j]) j -- ;
            else i ++ ;
        }
        return res;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/2115435/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

15.三数之和

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        for(int i = 0; i < nums.size(); i ++ )
        {
            if(i > 0 && nums[i] == nums[i - 1]) continue;
            for(int j = i + 1, k = nums.size() - 1; j < k; j ++ )
            {
                if(j > i + 1 && nums[j] == nums[j - 1]) continue;
                while(j < k - 1 && nums[i] + nums[j] + nums[k - 1] >= 0) k -- ;
                if(nums[i] + nums[j] + nums[k] == 0) 
                {
                    res.push_back({nums[i], nums[j], nums[k]});
                }
            }
        }
        return res;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3852675/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

17. 电话号码的字母组合

class Solution {
public:
    vector<string> ans;
    string strs[10] = {
        "", "", "abc", "def",
        "ghi", "jkl", "mno",
        "pqrs", "tuv", "wxyz",
    };

    void dfs(string& digits, int u, string path)
    {
        if(u == digits.size()) ans.push_back(path);
        else
        {
            for(auto c : strs[digits[u] - '0'])
            {
                dfs(digits, u + 1, path + c);
            }
        }
    }

    vector<string> letterCombinations(string digits) {
        if(digits.empty()) return ans;
        dfs(digits, 0, "");
        return ans;
    }
};

19. 删除链表的倒数第 N 个结点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int k) {
        //建立一个虚拟头结点,因为头结点可能会被删掉,这样便于操作
        auto dummy = new ListNode(-1);
        dummy->next = head;
        
        int len = 0; //计算链表长度
        for(auto p = dummy; p; p = p->next) len ++ ;

        auto p = dummy;
        //跳到要删除节点的前一个点,然后p->next = p->next->next;
        for(int i = 0; i < len - k - 1; i ++ ) p = p->next;
        p->next = p->next->next;

        return dummy->next;
    }
};

20. 有效的括号

方法一

class Solution {
public:
    stack<char> stk;
    bool isValid(string s) {
        for(auto c : s)
        {
            if(stk.empty() || c == '(' || c == '[' || c == '{') stk.push(c);
            else if(stk.top() == '(' && c == ')') stk.pop();
            else if(stk.top() == '[' && c == ']') stk.pop();
            else if(stk.top() == '{' && c == '}') stk.pop();
            else return false;
        }
        if(!stk.empty()) return false;
        return true;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3856042/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法二

class Solution {
public:
    stack<char> stk;
    bool isValid(string s) {
        for(auto c : s)
        {
            if(c == '(' || c == '[' || c == '{') stk.push(c);
            else
            {   // 左右括号的ASCII码值相差不超过2
                if(stk.size() && abs(stk.top() - c) <= 2) stk.pop();
                else return false;
            }
        }
        return stk.empty();
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3856042/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

21. 合并两个有序链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        auto dummy = new ListNode(-1), tail = dummy;
        while(l1 && l2)
        {
            if(l1->val < l2->val)
            {
                tail = tail->next = l1;
                l1 = l1->next;
            }
            else
            {
                tail = tail->next = l2;
                l2 = l2->next;
            }
        }
        if(l1) tail->next = l1;
        if(l2) tail->next = l2;
        return dummy->next;
    }
};

22. 括号生成

class Solution {
public:
    vector<string> res;
    void dfs(int n, int lcnt, int rcnt, string seq)
    {
        if(lcnt == n && rcnt == n) res.push_back(seq);
        else
        {
            if(lcnt < n) dfs(n, lcnt + 1, rcnt, seq + '(');
            if(rcnt < n && lcnt > rcnt) dfs(n, lcnt, rcnt + 1, seq + ')');
        }
    }
    
    vector<string> generateParenthesis(int n) {
        //合法括号序列满足:任意前缀中左括号数量大于等于右括号数量,且左右括号总数相同
        dfs(n, 0, 0, "");
        return res;
    }
};

23. 合并K个升序链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    struct Cmp // 比较函数
    {
        bool operator() (ListNode* a, ListNode* b)
        {
            return a->val > b->val;
        }
    };
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<ListNode*, vector<ListNode*>, Cmp> heap;
        auto dummy = new ListNode(-1), tail = dummy;
        for(auto l : lists) if(l) heap.push(l);

        //用堆来维护k个指针
        while(heap.size())
        {
            auto t = heap.top();
            heap.pop();
            // 将当前节点插入到尾结点的后面,然后更新当前节点为尾结点
            tail = tail->next = t;
            if(t->next) heap.push(t->next);
        }
        return dummy->next;
    }
};

31. 下一个排列

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int k = nums.size() - 1; // k为最后一个数的下标(下标从0开始)
        //从后往前找,找到第一个逆序的位置
        while(k > 0 && nums[k - 1] >= nums[k]) k -- ;
        //停下来后,nums[k]是从后往前第一个逆序对中较大的数
        if(k <= 0) //整个序列逆序,直接翻转
        {
            reverse(nums.begin(), nums.end());
        }
        else
        {
            int t = k;
            while(t < nums.size() && nums[t] > nums[k - 1]) t ++ ;
            //nums[k - 1]要与nums[k]后面大于等于nums[k - 1]的最小的数交换
            swap(nums[t - 1], nums[k - 1]);
            reverse(nums.begin() + k, nums.end());
        }
    }
};

32. 最长有效括号

合法括号满足两个条件:
1.任意前缀中左括号数量大于等于右括号数量
2.左右括号数量相等

class Solution {
public:
    int longestValidParentheses(string s) {
        stack<int> stk;
        int res = 0;
        for(int i = 0, start = -1; i < s.size(); i ++ )
        {
            if(s[i] == '(') stk.push(i);
            else //右括号
            {
                if(stk.size())  // 栈不空
                {
                    stk.pop(); // 当前右括号与栈顶左括号匹配,弹出栈顶左括号
                    if(stk.size()) // 如果栈不空
                    {
                        res = max(res, i - stk.top());
                    }
                    else 
                    {
                        // 弹出栈顶后栈为空,则长度为start+1到末尾i的长度
                        res = max(res, i - (start + 1) + 1);
                    }
                }
                else // 栈空
                {
                    //说明当前右括号是分界点,更新start
                    start = i;
                }
            }
        }
        return res;
    }
};

33. 搜索旋转排序数组

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty()) return -1;
        int l = 0, r = nums.size() - 1;
        while(l < r)
        {
            int mid = l + r + 1 >> 1;
            if(nums[mid] >= nums[0]) l = mid;
            else r = mid - 1;
        }

        if(target >= nums[0]) l = 0;
        else l = r + 1, r = nums.size() - 1;

        while(l < r)
        {
            int mid = l + r >> 1;
            if(nums[mid] >= target) r = mid;
            else l = mid + 1;
        }
        if(target == nums[r]) return r;
        return -1;
    }
};

34. 在排序数组中查找元素的第一个和最后一个位置

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(nums.empty()) return {-1, -1};
        int l = 0, r = nums.size() - 1;
        while(l < r)
        {
            int mid = l + r >> 1;
            if(nums[mid] >= target) r = mid;
            else l = mid + 1;
        }
        if(nums[r] != target) return {-1, -1};
        int L = r;
        l = r, r = nums.size() - 1;
        while(l < r)
        {
            int mid = l + r + 1 >> 1;
            if(nums[mid] <= target) l = mid;
            else r = mid - 1;
        }
        return {L, r};
    }
};

39. 组合总和

class Solution {
public:
    vector<int> path;
    vector<vector<int>> res;

    void dfs(vector<int>& c, int u, int target)
    {
        if(target == 0)
        {
            res.push_back(path);
            return;
        }
        if(u == c.size()) return;

        for(int i = 0; c[u] * i <= target; i ++ )
        {
            dfs(c, u + 1, target - c[u] * i);
            path.push_back(c[u]);
        }
        for(int i = 0; c[u] * i <= target; i ++ )
        {
            path.pop_back();
        }
    }

    vector<vector<int>> combinationSum(vector<int>& c, int target) {
        dfs(c, 0, target);
        return res;
    }
};

42. 接雨水

const int N = 2e4 + 10;
int q[N];
class Solution {
public:
    int trap(vector<int>& h) {
        int tt = -1;
        int res = 0;
        for(int i = 0; i < h.size(); i ++ )
        {
            int last = 0;
            while(tt >= 0 && h[q[tt]] <= h[i]) 
            {
                res += (h[q[tt]] - last) * (i - q[tt] - 1);
                last = h[q[tt]];
                tt -- ;
            }
            if(tt >= 0) res += (h[i] - last) * (i - q[tt] - 1);
            q[++ tt] = i;
        }
        return res;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3231169/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

46. 全排列

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    vector<bool> st;
    void dfs(vector<int>& nums, int u)
    {
        if(u == nums.size())
        {
            res.push_back(path);
            return;
        }
        for(int i = 0; i < nums.size(); i ++ )
        {
            if(!st[i])
            {
                st[i] = true;
                path[u] = nums[i];
                dfs(nums, u + 1);
                st[i] = false; 
            }
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        path = vector<int>(nums.size());
        st = vector<bool>(nums.size());
        dfs(nums, 0);
        return res;
    }   
};

48. 旋转图像

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        //按对角线翻转
        for(int i = 0; i < n; i ++ )
            for(int j = 0; j < i; j ++ )
                swap(matrix[i][j], matrix[j][i]);
        //左右翻转
        for(int i = 0; i < n; i ++ )
            for(int j = 0, k = n - 1; j < k; j ++, k -- )
                swap(matrix[i][j], matrix[i][k]);
    }
};

49. 字母异位词分组

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        //只需要把每个单词排序一下,两个单词如果排序之后得到的字符串相同
        //则说明是字母异位词
        unordered_map<string, vector<string>> hash;
        for(auto& str : strs)
        {
            string s = str;
            sort(s.begin(), s.end());
            hash[s].push_back(str);
        }
        vector<vector<string>> res;
        for(auto& it : hash) res.push_back(it.second);
        return res;
    }
};

53. 最大子数组和

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int res = INT_MIN;
        for(int i = 0, last = 0; i < nums.size(); i ++ )
        {
            last = nums[i] + max(last, 0);
            res = max(res, last);
        }
        return res;
    }
};

55. 跳跃游戏

class Solution {
public:
    bool canJump(vector<int>& nums) {
        for(int i = 0, j = 0; i < nums.size(); i ++ )
        {
            if(j < i) return false;
            j = max(j, i + nums[i]);
        }
        return true;
    }
};

56. 合并区间

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& a) {
        vector<vector<int>> res;
        if(a.empty()) return res;

        sort(a.begin(), a.end());
        int l = a[0][0], r = a[0][1];
        for(int i = 1; i < a.size(); i ++ )
        {
            if(r < a[i][0])
            {
                res.push_back({l, r});
                l = a[i][0], r = a[i][1];
            }
            else if(r < a[i][1]) r = a[i][1];
        }
        res.push_back({l, r});
        return res;
    }
};

62. 不同路径

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> f(m, vector<int>(n));
        for(int i = 0; i < m; i ++ )
            for(int j = 0; j < n; j ++ )
            {
                if(!i && !j) f[i][j] = 1;
                else
                {
                    if(i) f[i][j] += f[i - 1][j];
                    if(j) f[i][j] += f[i][j - 1];
                }
            }
        return f[m - 1][n - 1];
    }
};

64. 最小路径和

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int n = grid.size();
        if(!n) return 0;
        int m = grid[0].size();
        vector<vector<int>> f(n, vector<int>(m, INT_MAX));

        for(int i = 0; i < n; i ++ )
            for(int j = 0; j < m; j ++ )
            {
                if(!i && !j) f[i][j] = grid[i][j];
                else 
                {
                    if(i) f[i][j] = min(f[i][j], f[i - 1][j] + grid[i][j]);
                    if(j) f[i][j] = min(f[i][j], f[i][j - 1] + grid[i][j]);
                }
            }
        return f[n - 1][m - 1];
    }
};

70. 爬楼梯

求斐波那契数列第n项

class Solution {
public:
    int climbStairs(int n) {
        int a = 1, b = 1;
        while(-- n)
        {
            int c = a + b;
            a = b, b = c;
        }
        return b;
    }
};

72. 编辑距离

image

class Solution {
public:
    int minDistance(string a, string b) {
        int n = a.size(), m = b.size();
        a = ' ' + a, b = ' ' + b;

        vector<vector<int>> f(n + 1, vector<int>(m + 1, 1e9));
        for(int i = 0; i <= n; i ++ ) f[i][0] = i;
        for(int i = 0; i <= m; i ++ ) f[0][i] = i;

        for(int i = 1; i <= n; i ++ )
            for(int j = 1; j <= m; j ++ )
            {
                f[i][j] = min(f[i - 1][j], f[i][j - 1]) + 1;
                int t = a[i] != b[j];
                f[i][j] = min(f[i][j], f[i - 1][j - 1] + t);
            }
        return f[n][m];
    }
};

75. 颜色分类

法一:荷兰国旗问题
固定套路,背会即可。

class Solution {
public:
    void sortColors(vector<int>& nums) {
        for(int i = 0, j = 0, k = nums.size() - 1; i <= k;)
        {
            if(nums[i] == 0) swap(nums[i ++ ], nums[j ++ ]);
            else if(nums[i] == 2) swap(nums[i], nums[k -- ]);
            else i ++ ;
        }
    }
};

法二:快速排序

class Solution {
public:
    void quick_sort(vector<int>& q, int l, int r)
    {
        if(l >= r) return;
        int x = q[l + r >> 1], i = l - 1, j = r + 1;
        while(i < j)
        {
            while(q[++ i] < x);
            while(q[-- j] > x);
            if(i < j) swap(q[i], q[j]);
        }
        quick_sort(q, l, j), quick_sort(q, j + 1, r);
    }
    void sortColors(vector<int>& nums) {
        quick_sort(nums, 0, nums.size() - 1);
    }
};

76. 最小覆盖子串

双指针+哈希表

class Solution {
public:
    string minWindow(string s, string t) {
        unordered_map<char, int> hs, ht;
        for(auto c : t) ht[c] ++ ;

        string res;
        int cnt = 0;
        for(int i = 0, j = 0; i < s.size(); i ++ )
        {
            hs[s[i]] ++ ;
            if(hs[s[i]] <= ht[s[i]]) cnt ++ ;
            while(hs[s[j]] > ht[s[j]]) hs[s[j ++ ]] -- ;
            if(cnt == t.size())
            {
                if(res.empty() || i - j + 1 < res.size())
                    res = s.substr(j, i - j + 1);
            }
        }
        return res;
    }
};

78. 子集

法一:DFS

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    void dfs(vector<int>& nums, int u)
    {
        if(u >= nums.size()) 
        {
            res.push_back(path);
            return;
        }
        //不选当前数
        dfs(nums, u + 1);

        //选当前数
        path.push_back(nums[u]);
        dfs(nums, u + 1);
        path.pop_back();
    }
    vector<vector<int>> subsets(vector<int>& nums) {
        dfs(nums, 0);
        return res;
    }
};

法二:二进制枚举

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        int n = nums.size();
        vector<vector<int>> res;
        //二进制枚举,0~(2^n)-1
        for(int i = 0; i < 1 << n; i ++ )
        {
            vector<int> path;
            for(int j = 0; j < n; j ++ )
                if(i >> j & 1)
                    path.push_back(nums[j]);
            res.push_back(path);
        }
        return res;
    }
};

79. 单词搜索

class Solution {
public:
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    bool dfs(vector<vector<char>>& board, string &word, int u, int x, int y)
    {
        if(board[x][y] != word[u]) return false;
        if(u == word.size() - 1) return true;
        
        char t = board[x][y];
        board[x][y] = '.';
        for(int i = 0; i < 4; i ++ )
        {
            int a = x + dx[i], b = y + dy[i];
            if(a < 0 || a >= board.size() || b < 0 || b >= board[0].size() || board[a][b] == '.') continue;
            if(dfs(board, word, u + 1, a, b)) return true;
        }
        board[x][y] = t; //恢复现场,第一次忘了
        return false;
    }

    bool exist(vector<vector<char>>& board, string word) {
        int n = board.size();
        for(int i = 0; i < n; i ++ )
            for(int j = 0; j < board[i].size(); j ++ )
                if(dfs(board, word, 0, i, j)) 
                    return true;
        return false;
    }
};

84. 柱状图中最大的矩形

单调栈

class Solution {
public:
    int largestRectangleArea(vector<int>& h) {
        int n = h.size();
        vector<int> l(n), r(n);
        stack<int> stk;

        for(int i = 0; i < n; i ++ )
        {
            while(stk.size() && h[stk.top()] >= h[i]) stk.pop();
            if(stk.size() == 0) l[i] = -1;
            else l[i] = stk.top();
            stk.push(i);
        }

        stk = stack<int>();
        for(int i = n - 1; i >= 0; i -- )
        {
            while(stk.size() && h[stk.top()] >= h[i]) stk.pop();
            if(stk.size() == 0) r[i] = n;
            else r[i] = stk.top();
            stk.push(i);
        }

        int res = 0;
        for(int i = 0; i < n; i ++ )
            res = max(res, h[i] * (r[i] - l[i] - 1));

        return res;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3231358/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

85. 最大矩形

单调栈

class Solution {
public:
    int work(vector<int>& h)
    {
        int n = h.size();
        vector<int> l(n), r(n);
        stack<int> stk;

        for(int i = 0; i < n; i ++ )
        {
            while(stk.size() && h[stk.top()] >= h[i]) stk.pop();
            if(stk.empty()) l[i] = -1;
            else l[i] = stk.top();
            stk.push(i);
        }

        stk = stack<int>();
        for(int i = n - 1; i >= 0; i -- )
        {
            while(stk.size() && h[stk.top()] >= h[i]) stk.pop();
            if(stk.empty()) r[i] = n;
            else r[i] = stk.top();
            stk.push(i);
        }

        int res = 0;
        for(int i = 0; i < n; i ++ )
            res = max(res, h[i] * (r[i] - l[i] - 1));

        return res;
    }

    int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.empty() || matrix[0].empty()) return 0;

        int n = matrix.size(), m = matrix[0].size();

        vector<vector<int>> h(n, vector<int>(m)); // 初始化n * m二维矩阵h
        for(int i = 0; i < n; i ++ )
            for(int j = 0; j < m; j ++ )
                if(matrix[i][j] == '1') 
                    if(i) h[i][j] = h[i - 1][j] + 1;
                    else h[i][j] = 1;

        int res = 0;
        for(int i = 0; i < n; i ++ ) res = max(res, work(h[i]));
        return res;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3232747/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

94. 二叉树的中序遍历

递归写法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> res;
    void dfs(TreeNode* root)
    {
        if(!root) return;
        dfs(root->left);
        res.push_back(root->val);
        dfs(root->right);
    }

    vector<int> inorderTraversal(TreeNode* root) {
        dfs(root);
        return res;    
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3201627/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

迭代写法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> res;
    void dfs(TreeNode* root)
    {
        if(!root) return;
        dfs(root->left);
        res.push_back(root->val);
        dfs(root->right);
    }

    vector<int> inorderTraversal(TreeNode* root) {
        dfs(root);
        return res;    
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3201627/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

96. 不同的二叉搜索树

class Solution {
public:
    int numTrees(int n) {
        vector<int> f(n + 1);
        f[0] = 1;
        for(int i = 1; i <= n; i ++ )
            for(int j = 1; j <= i; j ++ )
                f[i] += f[j - 1] * f[i - j];
        return f[n];
    }
};

98. 验证二叉搜索树

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> dfs(TreeNode* root)
    {
        vector<int> res({1, root->val, root->val});
        if(root->left)
        {
            auto t = dfs(root->left);
            if(!t[0] || t[2] >= root->val) res[0] = 0;
            res[2] = max(res[2], t[2]);
            res[1] = min(res[1], t[1]);
        }
        if(root->right)
        {
            auto t = dfs(root->right);
            if(!t[0] || t[1] <= root->val) res[0] = 0;
            res[2] = max(res[2], t[2]);
            res[1] = min(res[1], t[1]);
        }
        return res;
    }
    bool isValidBST(TreeNode* root) {
        if(!root) return true;
        return dfs(root)[0];
    }
};

101. 对称二叉树

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool dfs(TreeNode* p, TreeNode *q)
    {
        if(!p && !q) return true;
        if(!p || !q || p->val != q->val) return false;
        return dfs(p->left, q->right) && dfs(p->right, q->left);
    }
    bool isSymmetric(TreeNode* root) {
        if(!root) return true;
        return dfs(root->left, root->right);
    }
};

102. 二叉树的层序遍历

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        queue<TreeNode*> q;
        if(root) q.push(root);

        while(q.size())
        {
            vector<int> level; // 存每层的节点
            int len = q.size(); // len为当前层节点数
            while(len -- )
            {
                auto t = q.front();
                q.pop();
                level.push_back(t->val);
                if(t->left) q.push(t->left);
                if(t->right) q.push(t->right);
            }
            res.push_back(level);
        }
        return res;
    }
};

104. 二叉树的最大深度

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(!root) return 0;
        return max(maxDepth(root->left), maxDepth(root->right)) + 1;
    }
};

105. 从前序与中序遍历序列构造二叉树

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    unordered_map<int, int> pos;
    TreeNode* build(vector<int>& preorder, vector<int>& inorder, int pl, int pr, int il, int ir)
    {
        if(pl > pr) return NULL;
        auto root = new TreeNode(preorder[pl]);
        int k = pos[root->val];
        root->left = build(preorder, inorder, pl + 1, pl + 1 + k - 1 - il, il, k - 1);
        root->right = build(preorder, inorder, pl + 1 + k - 1 - il + 1, pr, k + 1, ir);
        return root; 
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        for(int i = 0; i < inorder.size(); i ++ ) pos[inorder[i]] = i;
        return build(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
    }
};

114. 二叉树展开为链表

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void flatten(TreeNode* root) {
        while(root)
        {
            auto p = root->left;
            if(p)
            {
                while(p->right) p = p->right;
                p->right = root->right;
                root->right = root->left;
                root->left = NULL;
            }
            root = root->right;
        }
    }
};

121. 买卖股票的最佳时机

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int res = 0;
        for(int i = 0, minv = 1e9; i < prices.size(); i ++ )
        {
            res = max(res, prices[i] - minv);
            minv = min(minv, prices[i]);
        }
        return res;
    }
};

124. 二叉树中的最大路径和

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int res;
    int dfs(TreeNode* root)
    {
        if(!root) return 0;
        int left = max(0, dfs(root->left)), right = max(0, dfs(root->right));
        res = max(res, root->val + left + right);
        return root->val + max(left, right);
    }
    int maxPathSum(TreeNode* root) {
        res = -1e9;
        dfs(root);
        return res;
    }
};

128. 最长连续序列

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> S;
        for(auto x : nums) S.insert(x);
        int res = 0;
        for(auto x : nums)
        {
            if(S.count(x) && !S.count(x - 1))
            {
                int y = x;
                S.erase(x);
                while(S.count(y + 1))
                {
                    y ++ ;
                    S.erase(y);
                }
                res = max(res, y - x + 1);
            }
        }
        return res;
    }
};

136. 只出现一次的数字

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        for (int i = 1; i < nums.size(); i ++ )
            nums[0] ^= nums[i];
        return nums[0];
    }
};

139. 单词拆分

写法一:

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        const int P = 131;
        typedef unsigned long long ULL;
        unordered_set<ULL> S;

        for (auto word: wordDict)
        {
            ULL h = 0;
            for (auto& c: word) h = h * P + c;
            S.insert(h);            
        }
        
        int n = s.size();
        vector<bool> f(n + 1);
        f[n] = true;
        for (int i = n - 1; i >= 0; i -- )
        {
            ULL h = 0;
            for (int j = i; j < n; j ++ )
            {
                h = h * P + s[j];
                if (S.count(h) && f[j + 1])
                {
                    f[i] = true;
                    break;
                }
            }
        }
        return f[0];
    }
};

写法二:

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        const int P = 131;
        typedef unsigned long long ULL;
        unordered_set<ULL> S;

        for (auto word: wordDict)
        {
            ULL h = 0;
            for (auto& c: word) h = h * P + c;
            S.insert(h);            
        }
        
        int n = s.size();
        vector<bool> f(n + 1);
        f[0] = true;
        s = ' ' + s; // 下标从1
        for (int i = 0; i < n; i ++ )
        { 
            if (f[i])
            {
                ULL h = 0;
                for (int j = i + 1; j <= n; j ++ )
                {
                    h = h * P + s[j];
                    if (S.count(h))
                    {
                        f[j] = true;
                    }
                }
            }
        }
        return f[n];
    }
};

141. 环形链表

快慢指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(!head || !head->next) return false;
        auto s = head, f = head->next;
        while(f)
        {
            s = s->next, f = f->next;
            if(!f) return false;
            f = f->next;
            if(f == s) return true;
        }
        return false;
    }
};

142. 环形链表 II

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(!head || !head->next) return NULL;
        auto s = head, f = head;
        while(f)
        {
            s = s->next;
            f = f->next;
            if(!f) return NULL;
            f = f->next;
            if(s == f)
            {
                s = head;
                while(s != f)
                {
                    s = s->next;
                    f = f->next;
                }
                return s;
            }
        }
        return NULL;
    }
};

146. LRU 缓存

双链表+哈希表

class LRUCache {
public:
    struct Node
    {
        int key, val;
        Node *left, *right;
        Node(int _key, int _val): key(_key), val(_val), left(NULL), right(NULL) {}
    }*L, *R;
    unordered_map<int, Node*> hash;
    int n;

    LRUCache(int capacity) {
        n = capacity;
        L = new Node(-1, -1), R = new Node(-1, -1);
        L->right = R;
        R->left = L;
    }

    void remove(Node* p)
    {
        p->left->right = p->right;
        p->right->left = p->left;
    }

    void insert(Node* p) 
    {
        p->right = L->right;
        p->left = L;
        L->right->left = p;
        L->right = p;
    }
    
    int get(int key) {
        if(hash.count(key) == 0) return -1;
        auto p = hash[key];
        remove(p);
        insert(p);
        return p->val;
    }
    
    void put(int key, int value) {
        if(hash.count(key))
        {
            auto p = hash[key];
            p->val = value;
            remove(p);
            insert(p);
        }
        else
        {
            if(hash.size() == n)
            {
                auto p = R->left;
                remove(p);
                hash.erase(p->key);
                delete p;
            }
            auto p = new Node(key, value);
            hash[key] = p;
            insert(p);
        }
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

148. 排序链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        int n = 0;
        for (auto p = head; p; p = p->next) n ++ ;

        auto dummy = new ListNode(-1);
        dummy->next = head;
        for (int i = 1; i < n; i *= 2) {
            auto cur = dummy;
            for (int j = 1; j + i <= n; j += i * 2) {
                auto p = cur->next, q = p;
                for (int k = 0; k < i; k ++ ) q = q->next;
                int x = 0, y = 0;
                while (x < i && y < i && p && q) {
                    if (p->val <= q->val) cur = cur->next = p, p = p->next, x ++ ;
                    else cur = cur->next = q, q = q->next, y ++ ;
                }
                while (x < i && p) cur = cur->next = p, p = p->next, x ++ ;
                while (y < i && q) cur = cur->next = q, q = q->next, y ++ ;
                cur->next = q;
            }
        }
        return dummy->next;
    }
};

152. 乘积最大子数组

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int res = nums[0];
        int f = nums[0], g = nums[0];
        for (int i = 1; i < nums.size(); i ++ ) 
        {
            int a = nums[i], fa = f * a, ga = g * a;
            f = max(a, max(fa, ga));
            g = min(a, min(fa, ga));
            res = max(res, f);
        }
        return res;
    }
};

155. 最小栈

class MinStack {
public:
    stack<int> stk;
    stack<int> stk_min;
    MinStack() {

    }
    
    void push(int val) {
        stk.push(val);
        if (stk_min.size()) {
            int x = stk_min.top();
            stk_min.push(min(x, val));
        } else {
            stk_min.push(val);
        }
    }
    
    void pop() {
        stk.pop();
        stk_min.pop();
    }
    
    int top() {
        return stk.top();
    }
    
    int getMin() {
        return stk_min.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

160. 相交链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        auto p = headA, q = headB;
        while(p != q)
        {
            p = p ? p->next : headB;
            q = q ? q->next : headA;
        }
        return p;
    }
};

169. 多数元素(摩尔投票法)

摩尔投票法

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int val, cnt = 0;
        for(auto c : nums)
        {
            if(cnt == 0) val = c, cnt ++ ;
            else if(c == val) cnt ++ ;
            else cnt -- ;
        }
        return val;
    }
};

198. 打家劫舍

image

class Solution {
public:
    int rob(vector<int>& nums) {
        int n = nums.size();
        vector<int> f(n + 1), g(n + 1);
        for(int i = 1; i <= n; i ++ )
        {
            f[i] = g[i - 1] + nums[i - 1];
            g[i] = max(f[i - 1], g[i - 1]);
        }
        return max(f[n], g[n]);
    }
};

200. 岛屿数量

BFS写法

typedef pair<int, int> PII;
class Solution {
public:
    vector<vector<char>> g;
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 

    void bfs(int x, int y)
    {
        g[x][y] = '0';
        queue<PII> q;
        q.push({x, y});

        while(q.size())
        {
            PII t = q.front();
            q.pop();

            for(int i = 0; i < 4; i ++ )
            {
                int a = t.first + dx[i], b = t.second + dy[i];
                if(a >= 0 && a < g.size() && b >= 0 && b < g[a].size() && g[a][b] == '1')
                {
                    q.push({a, b});
                    g[a][b] = '0';
                }
            }
        }
    }

    int numIslands(vector<vector<char>>& grid) {
        g = grid;
        int res = 0;
        for(int i = 0; i < g.size(); i ++ )
            for(int j = 0; j < g[0].size(); j ++ )
                if(g[i][j] == '1')
                {
                    bfs(i, j);
                    res ++ ;
                }
        return res;
    }
};

DFS写法

class Solution {
public:
    vector<vector<char>> g;
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 

    void dfs(int x, int y)
    {
        g[x][y] = '0';
        for(int i = 0; i < 4; i ++ )
        {
            int a = x + dx[i], b = y + dy[i];
            if(a >= 0 && a < g.size() && b >= 0 && b < g[a].size() && g[a][b] == '1')
                dfs(a, b);
        }
    }

    int numIslands(vector<vector<char>>& grid) {
        g = grid;
        int res = 0;
        for(int i = 0; i < g.size(); i ++ )
            for(int j = 0; j < g[0].size(); j ++ )
                if(g[i][j] == '1')
                {
                    dfs(i, j);
                    res ++ ;
                }
        return res;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/4095528/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

206. 反转链表

迭代做法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head || !head->next) return head; // 如果是空节点或只有一个结点,直接返回

        auto a = head, b = a->next;
        while(b)
        {
            auto c = b->next;
            b->next = a;
            a = b, b = c;
        }
        head->next = NULL;
        return a; //此时a为原来的尾结点,即反转链表后的新结点
    }
};

递归做法


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head || !head->next) return head;
        auto tail = reverseList(head->next);
        head->next->next = head;
        head->next = NULL;
        return tail;
    }
};

207. 课程表

拓扑排序

class Solution {
public:
    bool canFinish(int n, vector<vector<int>>& edges) {
        vector<vector<int>> g(n);
        vector<int> d(n);

        for(auto& e : edges)
        {
            int b = e[0], a = e[1];
            g[a].push_back(b);
            d[b] ++ ;
        }

        queue<int> q;
        for(int i = 0; i < n; i ++ )
            if(!d[i])
                q.push(i);

        int cnt = 0;
        while(q.size())
        {
            int t = q.front();
            q.pop();
            cnt ++ ;
            for(auto j : g[t])
            {
                if(-- d[j] == 0)
                    q.push(j);
            }
        }
        return cnt == n;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3062261/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

208. 实现 Trie (前缀树)

class Trie {
public:
    struct Node
    {
        Node* son[26];
        bool is_end;

        Node() 
        {
            for(int i = 0; i < 26; i ++ ) son[i] = NULL;
            is_end = false;
        }
    }*root;

    Trie() {
        root = new Node();
    }

    void insert(string word) {
        auto p = root;
        for(auto c : word)
        {
            int u = c - 'a';
            if(!p->son[u]) p->son[u] = new Node();
            p = p->son[u];
        }
        p->is_end = true;
    }

    bool search(string word) {
        auto p = root;
        for(auto c : word)
        {
            int u = c - 'a';
            if(!p->son[u]) return false;
            p = p->son[u];
        }
        return p->is_end;
    }

    bool startsWith(string prefix) {
        auto p = root;
        for(auto c : prefix)
        {
            int u = c - 'a';
            if(!p->son[u]) return false;
            p = p->son[u];
        }
        return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/3337748/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

215. 数组中的第K个最大元素

快速选择排序

class Solution {
public:
    int quick_sort(vector<int>& q, int l, int r, int k)
    {
        if(l == r) return q[k];
        int i = l - 1, j = r + 1, x = q[l + r >> 1];
        while(i < j)
        {
            while(q[++ i] > x); //求第k大元素,这里要写大于号,与快排相反
            while(q[-- j] < x); //写小于号,与快排相反
            if(i < j) swap(q[i], q[j]);
        }
        if(k <= j) return quick_sort(q, l, j, k);
        return quick_sort(q, j + 1, r, k);
    }
    int findKthLargest(vector<int>& nums, int k) {
        return quick_sort(nums, 0, nums.size() - 1, k - 1);
    }
};

221. 最大正方形

image
图片来源于题解:LeetCode 221. 最大正方形

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        if(matrix.empty() || matrix[0].empty()) return 0;
        int n = matrix.size(), m = matrix[0].size();

        vector<vector<int>> f(n + 1, vector<int>(m + 1));
        int res = 0;
        for(int i = 1; i <= n; i ++ )
            for(int j = 1; j <= m; j ++ )
                if(matrix[i - 1][j - 1] == '1')
                {
                    f[i][j] = min(f[i - 1][j], min(f[i - 1][j - 1], f[i][j - 1])) + 1;
                    res = max(res, f[i][j]);
                } 
        return res * res;
    }
};

226. 翻转二叉树

将左右子树对调,然后再递归地翻转左右子树本身

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(!root) return NULL;
        swap(root->left, root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
};

234. 回文链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int> q;
        for(auto p = head; p; p = p->next) q.push_back(p->val);
        for(int i = 0, j = q.size() - 1; i < j, j >= 0; i ++, j -- )
        {
            if(q[i] != q[j]) 
                return false;
        }
        return true;
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/4105150/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

236. 二叉树的最近公共祖先

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* res = NULL;

    int dfs(TreeNode* root, TreeNode* p, TreeNode* q)
    {
        if(!root) return 0;
        int state = dfs(root->left, p, q);
        if(root == p) state |= 1;
        else if(root == q) state |= 2;
        state |= dfs(root->right, p, q);
        if(state == 3 && !res) res = root;
        return state;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        dfs(root, p, q);
        return res;
    }
};

238. 除自身以外数组的乘积

在acwing题库上搜前后缀分解

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int n = nums.size();
        vector<int> p(n, 1); // 初始化为n个值为1的int
        for(int i = 1; i < n; i ++ ) p[i] = p[i - 1] * nums[i - 1];
        for(int i = n - 1, s = 1; i >= 0; i -- )
        {
            p[i] *= s;
            s *= nums[i];
        }
        return p;
    }
};

239. 滑动窗口最大值

单调队列

class Solution {
public:
    vector<int> res;
    deque<int> q;
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        for(int i = 0; i < nums.size(); i ++ )
        {
            if(q.size() && i - k + 1 > q.front()) q.pop_front();
            while(q.size() && nums[q.back()] <= nums[i]) q.pop_back();
            q.push_back(i);
            if(i >= k - 1) res.push_back(nums[q.front()]);
        }
        return res;
    }
};

240. 搜索二维矩阵 II

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.empty() || matrix[0].empty()) return false;
        int n = matrix.size(), m = matrix[0].size();
        int i = 0, j = m - 1;
        while(i < n && j >= 0)
        {
            int t = matrix[i][j];
            if(t == target) return true;
            else if(t > target) j -- ;
            else i ++ ;
        }
        return false;
    }
};

279. 完全平方数

勒让德三平方和定理、拉格朗日四平方和定理
由拉格朗日四平方和定理知,答案只能为1,2,3,4,挨个判断每个情况

class Solution {
public:
    bool check(int x)
    {
        int r = sqrt(x);
        return r * r == x;
    }
    int numSquares(int n) {
        // 判断1的情况
        if(check(n)) return 1;
        // 判断2的情况
        for(int a = 1; a <= n / a; a ++ )
            if(check(n - a * a))
                return 2;
        //判断3
        while(n % 4 == 0) n /= 4;
        if(n % 8 != 7) return 3;
        //以上三种情况都不是,则为4
        return 4;
    }
};

283. 移动零

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int k = 0;
        for(auto x : nums)
        {
            if(x)
                nums[k ++ ] = x;
        }
        while(k < nums.size()) nums[k ++ ] = 0;
    }
};

287. 寻找重复数

本题可以转化为142. 环形链表 II
相当于在链表中找环的入口

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int a = 0, b = 0;
        while(true)
        {
            a = nums[a];
            b = nums[nums[b]];
            if(a == b)
            {
                a = 0;
                while(a != b)
                {
                    a = nums[a];
                    b = nums[b];
                }
                return a;
            }
        }
        return -1;
    }
};

297. 二叉树的序列化与反序列化

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:
    string path;
    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        dfs_s(root);
        return path;
    }

    void dfs_s(TreeNode* root) {
        if (!root) {
            path += "#,";
        } else {
            path += to_string(root->val) + ',';
            dfs_s(root->left);
            dfs_s(root->right);
        }
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        int u = 0;
        return dfs_d(data, u);
    }

    TreeNode* dfs_d(string& data, int& u) {
        if (data[u] == '#') {
            u += 2;
            return NULL;
        } else {
            int k = u;
            while (data[u] != ',') u ++ ;
            auto root = new TreeNode(stoi(data.substr(k, u - k)));
            u ++ ;
            root->left = dfs_d(data, u);
            root->right = dfs_d(data, u);
            return root;
        }
    }
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

300. 最长递增子序列

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> q;   
        for(auto x : nums) 
        {
            if(q.empty() || x > q.back()) q.push_back(x);
            else
            {
                if(x <= q[0]) q[0] = x;
                else
                {
                    int l = 0, r = q.size() - 1;
                    while(l < r) 
                    {
                        int mid = l + r + 1 >> 1;
                        if(q[mid] < x) l = mid;
                        else r = mid - 1;
                    }
                    q[r + 1] = x;
                } 
            }
        }
        return q.size();
    }
};

作者:NFYD
链接:https://www.acwing.com/activity/content/code/content/2380007/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

301. 删除无效的括号

class Solution {
public:
    vector<string> res;
    /*
    合法括号序列性质:
    1.左右括号数量相等
    2.任意前缀中左括号数量>=右括号数量
    */
    vector<string> removeInvalidParentheses(string s) {
        int l = 0, r = 0; //l表示左括号数量-右括号数量, r表示当前要删掉多少个右括号
        for (auto x: s) {
            if (x == '(') l ++ ;
            else if (x == ')') {
                if (l == 0) r ++ ; // 左右括号数量相同,把右括号删掉,删掉右括号的数量++
                else l -- ; // (left - right) - 1
            }
        }
        dfs(s, 0, "", 0, l, r); // l 为要删掉左括号数量,r表示要删掉右括号的数量
        return res;
    }

    //cnt 表示左括号数量-右括号数量, l为当前可以删掉的左括号数量,r为当前可以删掉的右括号数量
    void dfs(string& s, int u, string path, int cnt, int l, int r) {
        if (u == s.size()) {
            if (!cnt) res.push_back(path);
            return;
        } 

        if (s[u] != '(' && s[u] != ')') {
            dfs(s, u + 1, path + s[u], cnt, l, r);
        } else if (s[u] == '(') {
            int k = u;
            while (k < s.size() && s[k] == '(') k ++ ;
            l -= k - u;
            for (int i = k - u; i >= 0; i -- ) {
                if (l >= 0) dfs(s, k, path, cnt, l, r);
                path += '(';
                cnt ++, l ++ ;
            }
        } else if (s[u] == ')') {
            int k = u;
            while (k < s.size() && s[k] == ')') k ++ ;
            r -= k - u;
            for (int i = k - u; i >= 0; i -- ) {
                if(cnt >= 0 && r >= 0) dfs(s, k, path, cnt, l, r);
                path += ')';
                cnt --, r ++ ;
            }
        }
    }
};

309. 最佳买卖股票时机含冷冻期

image

状态机DP

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.empty()) return 0;
        int n = prices.size(), INF = 1e9;
        vector<vector<int>> f(n, vector<int>(3, -INF));
        f[0][1] = -prices[0], f[0][0] = 0;
        for (int i = 1; i < n; i ++ ) {
            f[i][0] = max(f[i - 1][0], f[i - 1][2]);
            f[i][1] = max(f[i - 1][0] - prices[i], f[i - 1][1]);
            f[i][2] = f[i - 1][1] + prices[i];
        }
        return max(f[n - 1][0], max(f[n - 1][1], f[n - 1][2]));
    }
};

312. 戳气球

image

区间DP

class Solution {
public:
    int maxCoins(vector<int>& nums) {
        int n = nums.size();
        vector<int> a(n + 2, 1);
        for (int i = 1; i <= n; i ++ ) a[i] = nums[i - 1];

        vector<vector<int>> f(n + 2, vector<int>(n + 2));
        for (int len = 3; len <= n + 2; len ++ ) {
            for (int i = 0; i + len - 1 <= n + 1; i ++ ) {
                int j = i + len - 1;
                for (int k = i + 1; k < j; k ++ ) {
                    f[i][j] = max(f[i][j], f[i][k] + f[k][j] + a[i] * a[k] * a[j]);
                }
            }
        }
        return f[0][n + 1];
    }
};

322. 零钱兑换

完全背包问题

class Solution {
public:
    int coinChange(vector<int>& coins, int m) {
        vector<int> f(m + 1, 1e8);
        f[0] = 0;
        for (auto v: coins) 
            for (int j = v; j <= m; j ++ )
                f[j] = min(f[j], f[j - v] + 1);
        
        if (f[m] == 1e8) return -1;
        return f[m];
    }
};

337. 打家劫舍 III

树形DP
image

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int rob(TreeNode* root) {
        auto f = dfs(root);
        return max(f[0], f[1]);
    }

    vector<int> dfs(TreeNode* root) {
        if (!root) return {0, 0};
        auto x = dfs(root->left), y = dfs(root->right);
        return {max(x[0], x[1]) + max(y[0], y[1]), x[0] + y[0] + root->val};
    }
};

338. 比特位计数

class Solution {
public:
    vector<int> countBits(int n) {
        vector<int> f(n + 1);
        // 递推,i >> 1表示除了最后一位之外1的个数
        for (int i = 1; i <= n; i ++ )
            f[i] = f[i >> 1] + (i & 1);
        return f;
    }
};

347. 前 K 个高频元素

计数排序

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> cnt;
        for (auto x: nums) cnt[x] ++ ;

        int n = nums.size();
        vector<int> s(n + 1);
        for (auto it: cnt) s[it.second] ++ ;
        
        int i = n, t = 0;
        while (t < k) t += s[i -- ];

        vector<int> res;
        for (auto it: cnt)
            if (it.second > i)
                res.push_back(it.first);

        return res;
    }
};

394. 字符串解码

class Solution {
public:
    string decodeString(string s) {
        int u = 0;
        return dfs(s, u);
    }
    
    string dfs(string& s, int& u) {
        string res;
        while (u < s.size() && s[u] != ']') {
            if (isalpha(s[u])) {
                res += s[u ++ ];
            } else if (isdigit(s[u])) {
                int k = u;
                while (isdigit(s[k])) k ++ ;
                int x = stoi(s.substr(u, k - u));
                u = k + 1;
                string y = dfs(s, u);
                u ++ ; //过滤右括号
                while (x -- ) res += y;
            }
        }
        return res;
    }
};

399. 除法求值

class Solution {
public:
    vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
        unordered_set<string> vers;
        unordered_map<string, unordered_map<string, double>> d;

        for (int i = 0; i < equations.size(); i ++ ) {
            auto a = equations[i][0], b = equations[i][1];
            auto c = values[i];
            d[a][b] = c;
            d[b][a] = 1 / c;
            vers.insert(a);
            vers.insert(b);
        }
        //弗洛伊德算法
        for (auto k: vers) 
            for (auto i: vers) 
                for (auto j: vers)
                    if (d[i][k] && d[j][k])
                        d[i][j] = d[i][k] * d[k][j];
        
        vector<double> res;
        for (auto q: queries) {
            auto a = q[0], b = q[1];
            if (d[a][b]) res.push_back(d[a][b]);
            else res.push_back(-1);
        }
        return res;
    }
};

406. 根据身高重建队列

贪心思想 (二分+树状数组优化)

class Solution {
public:
    int n;
    vector<int> tr;

    int lowbit(int x) {
        return x & -x;
    }

    void add(int x, int c) {
        for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
    }

    int query(int x) {
        int res = 0;
        for (int i = x; i; i -= lowbit(i)) res += tr[i];
        return res;
    }

    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        n = people.size();
        tr.resize(n + 1);
        
        sort(people.begin(), people.end(), [](vector<int>& a, vector<int>& b) {
            if (a[0] != b[0]) return a[0] < b[0];
            return a[1] > b[1];
        });

        vector<vector<int>> res(n);
        for (auto p : people) {
            int h = p[0], k = p[1];
            int l = 1, r = n;
            while (l < r) {
                int mid = l + r >> 1;
                if (mid - query(mid) >= k + 1) r = mid;
                else l = mid + 1;
            }
            res[r - 1] = p;
            add(r, 1);
        }
        return res;
    }   
};

416. 分割等和子集

01背包问题

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int n = nums.size(), sum = 0;
        for (auto x: nums)  sum += x;
        if (sum % 2) return false;
        sum /= 2;

        vector<int> f(sum + 1);
        f[0] = 1;
        for (auto i: nums)
            for (int j = sum; j >= i; j -- )
                f[j] |= f[j - i];
        return f[sum];
    }
};

437. 路径总和 III

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    unordered_map<long long, long long> cnt;
    long long res = 0;

    long long pathSum(TreeNode* root, int target) {
        cnt[0] = 1;
        dfs(root, target, 0);
        return res;
    }

    void dfs(TreeNode* root, int target, long long cur) {
        if (!root) return;
        cur += root->val;
        res += cnt[cur - target];
        cnt[cur] ++ ;
        dfs(root->left, target, cur);
        dfs(root->right, target, cur);
        cnt[cur] -- ;
    }
};

438. 找到字符串中所有字母异位词

双指针维护滑动窗口

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        unordered_map<char, int> hash;
        for(auto c : p) hash[c] ++ ;
        vector<int> res;
        int tot = hash.size();
        for(int i = 0, j = 0, satisify = 0; i < s.size(); i ++ )
        {
            if(-- hash[s[i]] == 0) satisify ++ ;
            while(i - j + 1 > p.size())
            {
                if(hash[s[j]] == 0) satisify -- ;
                hash[s[j ++ ]] ++ ;
            }
            if(satisify == tot) res.push_back(j);
        }
        return res;
    }
};

写法二:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int cnt[26] = {0};
        int a = 0, b = 0;
        for(auto c : p) cnt[c - 'a'] ++ ;
        for(int i = 0; i < 26; i ++ ) if(cnt[i] != 0) a ++ ;
        vector<int> res;
        for(int l = 0, r = 0; r < s.size(); r ++ )
        {
            if(-- cnt[s[r] - 'a'] == 0) b ++ ;
            if(r - l + 1 > p.size() && ++ cnt[s[l ++ ] - 'a'] == 1) b -- ; 
            if(a == b) res.push_back(l);
        }
        return res;
    }
};

448. 找到所有数组中消失的数字

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        for (auto x: nums) {
            x = abs(x);
            if (nums[x - 1] > 0) nums[x - 1] *= -1;
        }
        vector<int> res;
        for (int i = 0; i < nums.size(); i ++ ) {
            if (nums[i] > 0)
                res.push_back(i + 1);
        }
        return res;
    }
};

494. 目标和

image

class Solution {
public:
    int findTargetSumWays(vector<int>& a, int target) {
        if (target < -1000 || target > 1000) return 0;
        int n = a.size(), offset = 1000;

        vector<vector<int>> f(n + 1, vector<int>(2001));
        f[0][0 + offset] = 1;
        for (int i = 1; i <= n; i ++ )
            for (int j = -1000; j <= 1000; j ++ ) {
                if (j - a[i - 1] >= -1000)
                    f[i][j + offset] += f[i - 1][j - a[i - 1] + offset];
                if (j + a[i - 1] <= 1000)
                    f[i][j + offset] += f[i - 1][j + a[i - 1] + offset];
            }
        return f[n][target + offset];
    }
};

538. 把二叉搜索树转换为累加树

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int sum = 0;
    TreeNode* convertBST(TreeNode* root) {
        dfs(root);
        return root;
    }

    void dfs(TreeNode* root) {
        if (!root) return;
        dfs(root->right);
        int x = root->val;
        root->val += sum;
        sum += x;
        dfs(root->left);
    }
};

543. 二叉树的直径

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int res = 0;
    int diameterOfBinaryTree(TreeNode* root) {
        dfs(root);
        return res;
    }
    
    int dfs(TreeNode* root) {
        if (!root) return 0;
        int left = dfs(root->left);
        int right = dfs(root->right);
        res = max(res, left + right);
        return max(left, right) + 1;
    }
};

560. 和为 K 的子数组

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int n = nums.size();
        vector<int> s(n + 1);
        for (int i = 1; i <= n; i ++ ) s[i] = s[i - 1] + nums[i - 1];
        unordered_map<int, int> hash;
        hash[0] = 1;
        int res = 0;
        for (int i = 1; i <= n; i ++ ) {
            res += hash[s[i] - k];
            hash[s[i]] ++ ;
        }
        return res;
    }
};

581. 最短无序连续子数组

class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        int l = 0, r = nums.size() - 1;
        while (l + 1 < nums.size() && nums[l + 1] >= nums[l]) l ++ ;
        if (l == r) return 0;
        while (r - 1 >= 0 && nums[r - 1] <= nums[r]) r -- ;
        
        for (int i = l + 1; i < nums.size(); i ++ ) 
            while (l >= 0 && nums[l] > nums[i]) 
                l -- ;
        
        for (int i = r - 1; i >= 0; i -- ) 
            while (r < nums.size() && nums[r] < nums[i]) 
                r ++ ; 
        
        return r - l - 1;
    }
};

617. 合并二叉树

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if (root2) swap(root1, root2);
        if (!root1) return NULL;
        root1->left = mergeTrees(root1->left, root2 ? root2->left : NULL);
        root1->right = mergeTrees(root1->right, root2 ? root2->right : NULL);
        if (root2) root1->val += root2->val;
        return root1;
    }
};

621. 任务调度器

class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        unordered_map<char, int> hash;
        for (auto c: tasks) hash[c] ++ ;
        int maxc = 0, cnt = 0;
        for (auto it: hash) maxc = max(maxc, it.second); //maxc为出现次数最多的数的个数
        for (auto it: hash) 
            if (maxc == it.second)
                cnt ++ ;
        
        return max((int)tasks.size(), (maxc - 1) * (n + 1) + cnt);
    }
};

647. 回文子串

class Solution {
public:
    int countSubstrings(string s) {
        int res = 0;
        for(int i = 0; i < s.size(); i ++ )
        {
            //枚举回文串长度为奇数的情况
            for(int j = i, k = i; j >= 0 && k < s.size(); j --, k ++ )
            {
                if(s[j] != s[k]) break;
                res ++ ;
            }

            //枚举回文串长度为偶数的情况
            for(int j = i, k = i + 1; j >= 0 && k < s.size(); j --, k ++ )
            {
                if(s[j] != s[k]) break;
                res ++ ;
            }
        }
        return res;
    }
};

739. 每日温度

单调栈

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& t) {
        vector<int> res(t.size());
        stack<int> stk;
        for (int i = t.size() - 1; i >= 0; i -- ) {
            while (stk.size() && t[i] >= t[stk.top()]) stk.pop();
            if (stk.size()) res[i] = stk.top() - i;
            stk.push(i);
        }
        return res;
    }   
};
posted @   Tshaxz  阅读(280)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
Language: HTML
点击右上角即可分享
微信分享提示