《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;
    }
};
相关推荐
毕竟是shy哥3 小时前
计算YOLO数据集中每个类的目标数
算法·yolo·机器学习
M78佐菲4 小时前
Linux学习笔记:TCP协议
linux·笔记·学习·tcp/ip·算法
圣保罗的大教堂4 小时前
leetcode 1406. 石子游戏 III 困难
leetcode
晊晌_h5 小时前
嵌入式从0到精通——数据结构总结[特殊字符]
数据结构·算法·排序算法
我找到地球的支点啦5 小时前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
罗西的思考6 小时前
【OpenClaw具身硬件】ZeroClaw 源码阅读笔记(3)--- RAG
人工智能·算法·机器学习
浪里镖客7 小时前
位姿转换矩阵写法-个人习惯(计算机理解其实是相反的)
线性代数·算法·矩阵
小白羊丨9 小时前
如何诊断 Prompt 模板导致的效果下降?
人工智能·算法·prompt
OPEN-F11 小时前
C++11/14新特性精讲:移动语义与智能指针实战
开发语言·c++·算法
lisin-lee-cooper11 小时前
【leetcode658】有序数组找出k个最接近x的数
java·数据结构·算法