《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;
    }
};
相关推荐
ZPC82104 小时前
双目相机 深度图和点云生成物体3D包围盒 生成抓取姿态
人工智能·数码相机·算法·yolo·计算机视觉
rGzywSmDg4 小时前
如何在Dev-C++中配置TDM-GCC编译器
开发语言·c++·算法
芜湖_4 小时前
LeetCode Hot 100 01 - 哈希
c++·算法·leetcode·哈希算法
浅念-4 小时前
LeetCode回溯算法从入门到精通完整解析
开发语言·数据结构·c++·算法·leetcode·dfs·深度优先遍历
青云计划4 小时前
数据库的ID的另一种选择-雪花算法
数据库·算法
夏日听雨眠4 小时前
linux(线程,线程同步 方法 互斥锁 信号量 条件变量 )
linux·运维·算法
神经网络机器学习智能算法画图绘图4 小时前
基于改进的支持向量机多分类预测研究
算法·支持向量机·分类
阿Y加油吧4 小时前
两道经典算法题复盘:最长有效括号 & 不同路径
算法
晚风叙码4 小时前
一文吃透二叉树:前中后序遍历+节点数+树高+叶子节点(含完整源码)
数据结构·算法