《LeetCode 顺序刷题》81 - 90

81、中等 搜索旋转排序数组 Ⅱ

数组 二分查找

复制代码
class Solution {
public:
    bool search(vector<int>& nums, int target) {
        int n = nums.size();
        if (n == 0) {
            return false;
        }
        if (n == 1) {
            return nums[0] == target;
        }
        int l = 0, r = n - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] == target) {
                return true;
            }
            if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
                ++l;
                --r;
            } else if (nums[l] <= nums[mid]) {
                if (nums[l] <= target && target < nums[mid]) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            } else {
                if (nums[mid] < target && target <= nums[n - 1]) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
        }
        return false;
    }
};

82、中等 删除排序链表中重复元素 Ⅱ

链表

复制代码
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (head == nullptr) {
            return nullptr;
        }

        ListNode newhead;
        newhead.next = head;
        ListNode* cur = &newhead;
        while (cur->next && cur->next->next) {
            if (cur->next->val == cur->next->next->val) {
                int x = cur->next->val;
                while (cur->next && cur->next->val == x) {
                    cur->next = cur->next->next;
                }
            } else {
                cur = cur->next;
            }
        }

        return newhead.next;
    }
};

83、简单 删除排序链表中的重复元素

链表

复制代码
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (head == nullptr) {
            return head;
        }
        ListNode* cur = head;
        while (cur->next) {
            ListNode* next = cur->next;
            if (cur->val == next->val) {
                cur->next = next->next;
                delete next;
            } else {
                cur = cur->next;
            }
        }
        return head;
    }
};

84、困难 柱状图中最大的矩形

数组

单调栈

复制代码
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        vector<int> left(n), right(n);

        stack<int> s;
        for (int i = 0; i < n; ++i) {
            while (!s.empty() && heights[s.top()] >= heights[i]) {
                s.pop();
            }
            left[i] = s.empty() ? -1 : s.top();
            s.push(i);
        }

        s = stack<int>();
        for (int i = n - 1; i >= 0; --i) {
            while (!s.empty() && heights[s.top()] >= heights[i]) {
                s.pop();
            }
            right[i] = s.empty() ? n : s.top();
            s.push(i);
        }

        int ret = 0;
        for (int i = 0; i < n; ++i) {
            ret = max(ret, (right[i] - left[i] - 1) * heights[i]);
        }
        return ret;
    }
};

单调栈+常数优化

复制代码
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        vector<int> left(n), right(n, n);

        stack<int> s;
        for (int i = 0; i < n; ++i) {
            while (!s.empty() && heights[s.top()] >= heights[i]) {
                right[s.top()] = i;
                s.pop();
            }
            left[i] = s.empty() ? -1 : s.top();
            s.push(i);
        }

        int ret = 0;
        for (int i = 0; i < n; ++i) {
            ret = max(ret, (right[i] - left[i] - 1) * heights[i]);
        }
        return ret;
    }
};

86、中等 分隔链表

链表

复制代码
class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode shead, *cur1 = &shead;
        ListNode lhead, *cur2 = &lhead;
        ListNode* cur = head;
        while (cur) {
            if (cur->val < x) {
                cur1->next = cur;
                cur1 = cur1->next;
            } else {
                cur2->next = cur;
                cur2 = cur2->next;
            }
            cur = cur->next;
        }
        cur1->next = lhead.next;
        cur2->next = nullptr;
        return shead.next;
    }
};

88、简单 合并两个有序数组

排序 数组 双指针

逆向双指针

复制代码
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int end1 = m - 1, end2 = n - 1;
        int end = m + n - 1;

        while (end1 >= 0 && end2 >= 0) {
            if (nums1[end1] > nums2[end2]) {
                nums1[end--] = nums1[end1--];
            } else {
                nums1[end--] = nums2[end2--];
            }
        }

        while (end2 >= 0) {
            nums1[end--] = nums2[end2--];
        }
    }
};

直接合并后排序

复制代码
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        for (int i = 0; i < n; i++) {
            nums1[m + i] = nums2[i];
        }
        sort(nums1.begin(), nums1.end());
    }
};

90、中等 子集 Ⅱ

迭代法实现子集枚举

复制代码
class Solution {
private:
    vector<int> path;
    vector<vector<int>> ret;

public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for (int mask = 0; mask < (1 << n); ++mask) {
            path.clear();
            bool flag = true;
            for (int i = 0; i < n; ++i) {
                if (mask & (1 << i)) {
                    if (i > 0 && (mask >> (i - 1) & 1) == 0 &&
                        nums[i] == nums[i - 1]) {
                        flag = false;
                        break;
                    }
                    path.push_back(nums[i]);
                }
            }
            if (flag) {
                ret.push_back(path);
            }
        }
        return ret;
    }
};

递归实现子集枚举

复制代码
class Solution {
private:
    vector<int> path;
    vector<vector<int>> ret;

    void dfs(bool choosePre, int cur, vector<int>& nums) {
        if (cur == nums.size()) {
            ret.push_back(path);
            return;
        }
        dfs(false, cur + 1, nums);
        if (!choosePre && cur > 0 && nums[cur - 1] == nums[cur]) {
            return;
        }
        path.push_back(nums[cur]);
        dfs(true, cur + 1, nums);
        path.pop_back();
    }

public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        dfs(false, 0, nums);
        return ret;
    }
};
相关推荐
雨白1 小时前
哈希:以时间换空间的算法实战
算法
San813_LDD3 小时前
[数据结构]LeetCode学习
数据结构·算法·图论
x138702859573 小时前
c语言排雷游戏(基础版9*9)
c语言·算法·游戏
sheeta19984 小时前
LeetCode 每日一题笔记 日期:2026.06.06 题目:2196. 根据描述创建二叉树
笔记·算法·leetcode
小欣加油4 小时前
leetcode994 腐烂的橘子
数据结构·c++·算法·leetcode·bfs
QuZero5 小时前
Guava Cache Deep Dive
java·后端·算法·guava
随意起个昵称5 小时前
线性dp-LIS题目4(A Twisty Movement)
算法·动态规划
Felven5 小时前
B. Fair Numbers
数据结构·算法
人道领域5 小时前
【LeetCode刷题日记】93.复原IP地址
java·开发语言·算法·leetcode