数据结构与算法

        1:编程语言中函数的调用

        2:操作系统中从用户态到内核寄存器的保存

        3:网络消息的处理。

class Solution
{
public:
    bool isValid(string s)
    {
        std::map<char, char> map = {
            {'(', ')'},
            {'[', ']'},
            {'{', '}'}};
        stack<char> stack;

        for (int i = 0; i < s.size(); i++)
        {
            if (s[i] == '(' || s[i] == '[' || s[i] == '{')
            {
                stack.push(s[i]);
            }
            else if (!stack.empty() && s[i] == map[stack.top()])
            {
                stack.pop();
            }
            else
            {
                return false;
            }
        }
        return stack.empty();
    }
};
class Solution:
    def isValid(self, s):
        dic = {'{': '}',  '[': ']', '(': ')'}  # 定义字典
        stack = []
        for c in s:
            if c in dic:
                stack.append(c)
            elif len(stack) != 0 and dic[stack[-1]] == c:
                stack.pop()
            else:
                return False
        return len(stack) == 0
  • demo2:

int solution(vector<int> size, vector<int> dir)
{
    stack<int> stack;
    stack.push(dir[0]);
    for (int i = 1; i < dir.size(); i++)
    {

        if (dir[i] == stack.top()) // 符号相同入栈
        {
            stack.push(dir[i]);
        }
        else
        {
            while (dir[i] == 0 && stack.top() == 1) // 符号不相同,
            {
                if (size[stack.top()] > size[i]) // 栈中元素大
                {
                    break;
                }
                else
                { // 栈中元素小,移除,如果栈大小为0,退出
                    stack.pop();
                    if (stack.empty())
                    {
                        stack.push(dir[i]);
                        break;
                    }
                }
            }
        }
    }
    return stack.size();
};
  • demo3

vector<int> FindRightSmall(vector<int> vec)
{
    stack<int> stack; // 单调递增栈
    vector<int> ret(vec.size());
    stack.push(0);
    for (int i = 1; i < vec.size(); i++)
    {
        if (vec[stack.top()] < vec[i]) // 当前元素大
        {
            stack.push(i);
        }
        else
        {
            while (!stack.empty() && vec[stack.top()] > vec[i]) // 当前元素小了,找到目标元素
            {
                ret[stack.top()] = i;
                stack.pop();
            }
            stack.push(i);
        }
    }

    while (!stack.empty())
    {
        ret[stack.top()] = -1;
        stack.pop();
    }
    return ret;
}
def FindRightSmall(vec):
    stack = []
    ret = [-1] * len(vec)
    stack.append(0)
    for iter in range(1, len(vec)):
        if (vec[stack[-1]] < vec[iter]):
            stack.append(iter)
        else:
            while (len(stack) != 0 and vec[stack[-1]] > vec[iter]):
                ret[stack[-1]] = iter
                stack.pop()
            stack.append(iter)

    while (len(stack) != 0):
        ret[stack[-1]] = -1
        stack.pop()
    return ret
  • demo4

vector<int> FindSmallNumber(vector<int> vec, int k)
{
    stack<int> stack; // 单调递增栈
    vector<int> ret(k);
    stack.push(0);
    for (int i = 1; i < vec.size(); i++)
    {
        if (vec[stack.top()] < vec[i]) // 如果右边的数大,放入
        {
            stack.push(i);
        }
        else
        {
            while (!stack.empty() && vec[stack.top()] > vec[i] && (stack.size() + vec.size() - i) > k) // 栈的个数加上剩余的元素大于k
            {
                stack.pop();
            }

            stack.push(i);
        }
    };

    while (stack.size() > k)
    {
        stack.pop();
    }
    for (int i = k - 1; i >= 0; i--)
    {
        ret[i] = vec[stack.top()];
        stack.pop();
    }

    return ret;
}
def FindSmallNumber(vec, k):
    stack = []
    ret = [0] * k
    stack.append(0)
    for iter in range(1, len(vec)):
        if (vec[stack[-1]] < vec[iter]):
            stack.append(iter)
        else:
            while (len(stack) != 0 and vec[stack[-1]] > vec[iter] and (len(stack) + len(vec)-iter > k)):
                stack.pop()

            stack.append(iter)

    while (len(stack) > k):
        stack.pop()
    for iter in range(k-1, -1, -1):
        ret[iter] = vec[stack[-1]]
        stack.pop()

    return ret

队列

  • demo1

102. 二叉树的层序遍历 - 力扣(LeetCode)

// 队列遍历
class Solution
{
public:
    vector<vector<int>> levelOrder(TreeNode *root)
    {
        if (root == nullptr)
        {
            return vector<vector<int>>();
        }

        vector<vector<int>> ret;
        vector<int> ret_index;
        queue<TreeNode *> que;
        que.push(root);
        while (!que.empty())
        {
            int size = que.size();
            for (int i = 0; i < size; i++)
            {
                TreeNode *cur = que.front();
                ret_index.push_back(cur->val);
                que.pop();

                if (cur->left != nullptr)
                {
                    que.push(cur->left);
                }
                if (cur->right != nullptr)
                {
                    que.push(cur->right);
                }
            }
            ret.push_back(ret_index);
            ret_index.clear();
        }
        return ret;
    }
};

// 顺序遍历
// vector遍历
class Solution
{
public:
    vector<vector<int>> levelOrder(TreeNode *root)
    {
        if (root == nullptr)
        {
            return vector<vector<int>>();
        }

        vector<vector<int>> ret;
        vector<int> ret_index;
        vector<TreeNode *> cur_level;
        vector<TreeNode *> next_level;

        if (root != nullptr)
        {
            cur_level.push_back(root);
        }

        while (!cur_level.empty())
        {
            for (auto iter : cur_level)
            {
                ret_index.push_back(iter->val);
                if (iter->left != nullptr)
                {
                    next_level.push_back(iter->left);
                };
                if (iter->right != nullptr)
                {
                    next_level.push_back(iter->right);
                };
            }
            ret.push_back(ret_index);
            ret_index.clear();
            cur_level = next_level;
            next_level.clear();
        }
        return ret;
    }
};
  • demo2 

622. 设计循环队列 - 力扣(LeetCode)

// 循环队列
// 放入元素rear+1,删除元素front+1
//[)
class MyCircularQueue
{
private:
    vector<int> que;
    int front = 0;
    int rear = 0;

public:
    MyCircularQueue(int k)
    {
        que.resize(k + 1);
    };

    bool enQueue(int value)
    {
        if (!isFull())
        {
            // 把元素放到rear位置
            que[rear] = value;
            // rear向后移动
            rear = (rear + 1) % que.size();
            return true;
        }
        else
        {
            return false;
        }
    };
    // 出队,不删除元素
    bool deQueue()
    {
        if (isEmpty())
        {
            return false;
        }
        else
        {
            front = (front + 1) % que.size();
            return true;
        }
    };

    int Front()
    {
        return isEmpty() ? -1 : que[front];
    };

    int Rear()
    {
        int tail = (rear + que.size() - 1) % que.size();
        return isEmpty() ? -1 : que[tail];
    };

    bool isEmpty()
    {
        return rear == front;
    };

    bool isFull()
    {
        return (rear + 1) % que.size() == front;
    };
};
  • demo3

239. 滑动窗口最大值 - 力扣(LeetCode)

// 非严格单调递减双端队列
class Solution
{
private:
    deque<int> que;
    vector<int> vec;

private:
    void DecreasingQueue(int index)
    {
        while (!que.empty() && vec[que.back()] <= vec[index])
        {
            que.pop_back();
        }
        que.push_back(index);
    }

public:
    vector<int> maxSlidingWindow(vector<int> &nums, int k)
    {
        vector<int> ret;
        // 单调递减队列
        vec = nums;
        for (int i = 0; i < k; i++)
        {
            DecreasingQueue(i);
        }
        ret.push_back(nums[que.front()]);
        for (int i = k; i < nums.size(); i++)
        {
            DecreasingQueue(i);
            // 第一个元素超过限制
            if (i - que.front() >= k)
            {
                que.pop_front();
            }
            ret.push_back(nums[que.front()]);
        };
        return ret;
    }
};
  • demo 4

1696. 跳跃游戏 VI - 力扣(LeetCode)

class Solution
{

public:
    int maxResult(vector<int> &nums, int k)
    {
        // 注意大根堆 pair 默认按 first排序
        std::priority_queue<pair<int, int>> prior_que; // 默认大根堆,小根堆 + std::greater<>

        prior_que.emplace(nums[0], 0);
        int ans = nums[0];
        for (int i = 1; i < nums.size(); i++)
        {
            // 为什么不用if 用 while
            // 新值会把旧值后移
            // 新值pop之后,旧值也必须pop
            while (i - prior_que.top().second > k)
            {
                prior_que.pop();
            }
            // 这里为什么要定义  prior_que.top().first
            // 因为必须要到达最后一个位置,最后一个值可能为负数
            ans = prior_que.top().first + nums[i];
            prior_que.push(make_pair(ans, i));
        }
        return ans;
    }
};

优先级队列

class Solution
{
public:
    vector<int> inventoryManagement(vector<int> &stock, int cnt)
    {
        vector<int> ret;
        ret.resize(cnt);
        priority_queue<int, vector<int>, greater<int>>
            small_que;

        for (int i = 0; i < stock.size(); i++)
        {
            small_que.emplace(stock[i]);
        }

        while (cnt--)
        {
            ret[cnt] = small_que.top();
            small_que.pop();
        }
        return ret;
    }
};
class Solution
{
public:
    vector<int> topKFrequent(vector<int> &nums, int k)
    {
        vector<int> ret;
        auto iter = [](pair<int, int> a, pair<int, int> b) -> bool
        {
            return a.second < b.second; // 大堆
        };
        priority_queue<pair<int, int>, vector<pair<int, int>>, function<bool(pair<int, int>, pair<int, int>)>> greater_queue(iter);

        unordered_map<int, int> temp_map;

        for (int i = 0; i < nums.size(); i++)
        {
            temp_map[nums[i]]++;
        }
        for (auto iter : temp_map)
        {
            greater_queue.push(iter);
        }

        while (k--)
        {
            ret.emplace_back(greater_queue.top().first);
            greater_queue.pop();
        }
        return ret;
    }
};

链表

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 *reverseList(ListNode *head)
    {
        ListNode *dummy_node = new ListNode();

        while (head != nullptr)
        {
            // update
            ListNode *temp = head->next;

            head->next = dummy_node->next;
            dummy_node->next = head;
            // update
            head = temp;
        }
        return dummy_node->next;
    }
};
class Solution
{
public:
    ListNode *deleteNode(ListNode *head, int val)
    {
        ListNode *dummy_list = new ListNode();
        ListNode *ret = dummy_list;
        while (head)
        {
            if (head->val != val)
            {
                dummy_list->next = head;
                dummy_list =  dummy_list->next;
            }
            head = head->next;
        }
        dummy_list->next = nullptr;
        return ret->next;
    }
};

demo3 83. 删除排序链表中的重复元素 - 力扣(LeetCode)

class Solution
{
public:
    ListNode *deleteDuplicates(ListNode *head)
    {
        ListNode *dummy_list = new ListNode();
        ListNode *ret = dummy_list;
        // 如何处理头节点?   dummy_list == ret
        while (head)
        {
            if (dummy_list == ret || dummy_list->val != head->val)
            {
                dummy_list->next = head;
                dummy_list = dummy_list->next;
            }
            head = head->next;
        }
        dummy_list->next = nullptr;
        return ret->next;
    }
};

demo421. 合并两个有序链表 - 力扣(LeetCode)

class Solution
{
public:
    ListNode *mergeTwoLists(ListNode *list1, ListNode *list2)
    {
        ListNode *dummy_list = new ListNode();
        ListNode *ret = dummy_list;

        while (list1 != nullptr && list2 != nullptr)
        {
            if (list1->val <= list2->val)
            {
                dummy_list->next = list1;
                list1 = list1->next;
            }
            else
            {
                dummy_list->next = list2;
                list2 = list2->next;
            }
            dummy_list = dummy_list->next;
        }
        if (list1 != nullptr)
        {
            dummy_list->next = list1;
        }
        if (list2 != nullptr)
        {
            dummy_list->next = list2;
        }
        return ret->next;
    }
};

demo523. 合并 K 个升序链表 - 力扣(LeetCode)

// 常规方法
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
    ListNode* list1_new = new ListNode(0);
    ListNode* list_head = list1_new;

    while (list1 != nullptr && list2 != nullptr) {
        if (list1->val <= list2->val) {
            list1_new->next = list1;
            list1 = list1->next;
        }
        else {
            list1_new->next = list2;
            list2 = list2->next;
        }
        list1_new = list1_new->next;
    }

    if (list1 != nullptr) {
        list1_new->next = list1;
    }
    else {
        list1_new->next = list2;
    }
    return list_head->next;
}

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {

        if (lists.size() == 0) {
            return nullptr;
        }

        ListNode* list_nodee = nullptr;
        for (int i = 0; i < lists.size(); i++)
        {
            ListNode* list_node = mergeTwoLists(list_nodee,lists[i]);
            list_nodee = list_node;
        }
        return list_nodee;
    }
};


// 小根堆
class Solution
{
private:
public:
    ListNode *
    mergeKLists(vector<ListNode *> &lists)
    {
        priority_queue<ListNode *, vector<ListNode *>, function<bool(ListNode *, ListNode *)>> small_que(
            [](ListNode *a, ListNode *b) -> bool
            {
                return a->val > b->val;
            });

        ListNode *dummy_list = new ListNode();
        ListNode *ret = dummy_list;

        for (auto iter : lists)
        {
            if (iter != nullptr)
            {
                small_que.push(iter);
            }
        }

        while (!small_que.empty())
        {
            ListNode *smaller = small_que.top();
            small_que.pop();
            // 更新结果
            dummy_list->next = smaller;
            dummy_list = dummy_list->next;

            // 更新小根堆
            if (smaller->next)
            {
                small_que.push(smaller->next);
            }
        }
        dummy_list->next = nullptr;
        return ret->next;
    }
};

demo619. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

class Solution
{
public:
    ListNode *removeNthFromEnd(ListNode *head, int n)
    {
        ListNode *dummy_list = new ListNode();
        dummy_list->next = head;
        ListNode *ret = dummy_list;
        ListNode *fast = dummy_list;
        int temp = n + 1;
        while (fast && temp--)
        {
            fast = fast->next;
        }

        while (dummy_list && fast)
        {
            fast = fast->next;
            dummy_list = dummy_list->next;
        }
        if (dummy_list && dummy_list->next)
        {
            dummy_list->next = dummy_list->next->next;
        }
        else
        {
            dummy_list->next = nullptr;
        }

        return ret->next;
    }
};

 树

demo1144. 二叉树的前序遍历 - 力扣(LeetCode)

// 递归
class Solution
{
    vector<int> res;

public:
    vector<int> preorderTraversal(TreeNode *root)
    {
        preorder(root);
        return res;
    }

private:
    void preorder(TreeNode *root)
    {
        if (root == nullptr)
        {
            return;
        }

        res.push_back(root->val);
        preorder(root->left);
        preorder(root->right);
    }
};

// 栈
class Solution
{
    vector<int> res;

public:
    vector<int> preorderTraversal(TreeNode *root)
    {
        stack<TreeNode *> stack;
        if (root == nullptr)
        {
            return res;
        }

        stack.push(root);
        while (!stack.empty())
        {
            TreeNode *cur = stack.top();
            res.push_back(cur->val);
            stack.pop();
            if (cur->right)
            {
                stack.push(cur->right);
            }
            if (cur->left)
            {
                stack.push(cur->left);
            }
        }

        return res;
    }
};

demo298. 验证二叉搜索树 - 力扣(LeetCode) 

// 递归
class Solution
{
    void preOrder(TreeNode *root, pair<int64_t, int64_t> section, bool &res)
    {
        if (!root || !res)
        {
            return;
        }

        if (section.first >= root->val || root->val >= section.second)
        {
            res = false;
            return;
        }
        preOrder(root->left, {section.first, root->val}, res);
        preOrder(root->right, {root->val, section.second}, res);
    }

public:
    bool isValidBST(TreeNode *root)
    {
        bool res = true;
        preOrder(root, {INT64_MIN, INT64_MAX}, res);
        return res;
    }
};

// 栈
class Solution
{

public:
    bool isValidBST(TreeNode *root)
    {

        stack<pair<TreeNode *, pair<int64_t, int64_t>>> stack;
        pair<int64_t, int64_t> section{INT64_MIN, INT64_MAX};

        if (root == nullptr)
        {
            return false;
        }
        stack.push(make_pair(root, section));
        while (!stack.empty())
        {
            auto iter = stack.top();
            TreeNode *cur = iter.first;
            pair<int64_t, int64_t> cur_section = iter.second;
            stack.pop();
            if (!(cur_section.first < cur->val && cur->val < cur_section.second))
            {
                return false;
            }

            if (cur->right)
            {
                stack.push(make_pair(cur->right, make_pair(cur->val, cur_section.second)));
            }
            if (cur->left)
            {
                stack.push(make_pair(cur->left, make_pair(cur_section.first, cur->val)));
            }
        }
        return true;
    }
};

 demo3113. 路径总和 II - 力扣(LeetCode)

class Solution
{
public:
    void back_track(TreeNode *node, vector<vector<int>> &res, vector<int> &res_index, int &targetsum)
    {
        if (!node)
        {
            return;
        }
        res_index.push_back(node->val);
        int sum = std::accumulate(res_index.begin(), res_index.end(), 0);
        if (!node->left && !node->right && targetsum == sum)
        {
            res.push_back(res_index);
        }

        back_track(node->left, res, res_index, targetsum);
        back_track(node->right, res, res_index, targetsum);
        // 回溯
        res_index.pop_back();
    }
    vector<vector<int>> pathSum(TreeNode *root, int targetSum)
    {
        vector<vector<int>> res;
        vector<int> res_index;
        back_track(root, res, res_index, targetSum);
        return res;
    }
};

数组

704. 二分查找 - 力扣(LeetCode)

class Solution
{
public:
    int search(vector<int> &nums, int target)
    {
        int left = 0;
        int right = nums.size() - 1;
        while (left <= right)
        {
            int middle = left + (right - left) / 2;

            if (nums[middle] == target)
            {
                return middle;
            }
            else if (nums[middle] < target)
            {
                left = middle + 1;
            }
            else
            {
                right = middle - 1;
            }
        }
        return -1;
    }
};

// 注意二分查找[left,right] 左闭右闭区间
// 区间迭代  middle

27. 移除元素 - 力扣(LeetCode)

class Solution
{
public:
    int removeElement(vector<int> &nums, int val)
    {
        int slow = 0;
        for (int fast = 0; fast < nums.size(); fast++)
        {
            if (nums[fast] != val)
            {
                nums[slow++] = nums[fast];
            }
        }
        nums.resize(slow);
        return slow;
    }
};
// 双指针

977. 有序数组的平方 - 力扣(LeetCode)

class Solution
{
public:
    vector<int> sortedSquares(vector<int> &nums)
    {
        int index = nums.size() - 1;
        vector<int> res(nums.size());
        int left = 0;
        int right = nums.size() - 1;
        while (left <= right)
        {
            if (nums[left] * nums[left] > nums[right] * nums[right])
            {
                res[index--] = nums[left] * nums[left];
                left++;
            }
            else
            {
                res[index--] = nums[right] * nums[right];
                right--;
            }
        }
        return res;
    }
};

209. 长度最小的子数组 - 力扣(LeetCode)

// 滑动窗口
class Solution
{
public:
    int minSubArrayLen(int target, vector<int> &nums)
    {
        int min = INT_MAX;
        int left = 0;
        int sum = 0;
        for (int right = 0; right < nums.size(); right++)
        {
            sum += nums[right];

            while (sum >= target)
            {
                min = std::min(min, right - left + 1); // 满足要求,left++
                sum -= nums[left++];
            }
        }
        return min == INT_MAX ? 0 : min;
    }
};

59. 螺旋矩阵 II - 力扣(LeetCode)

class Solution
{
public:
    vector<vector<int>> generateMatrix(int n)
    {
        vector<vector<int>> res(n, vector<int>(n));
        int left = 0;
        int right = n - 1;
        int up = 0;
        int down = n - 1;
        int num = 0;
        while (num != n * n)
        {
            // 上边 左 -> 右
            for (int i = left; i <= right; i++)
            {
                res[up][i] = ++num;
            }
            up++;
            // 右边 右 -> 右下
            for (int i = up; i <= down; i++)
            {
                res[i][right] = ++num;
            }
            right--;
            // 下边 右 -> 左
            for (int i = right; i >= left; i--)
            {
                res[down][i] = ++num;
            }
            down--;
            // 左边 左-> 左上
            for (int i = down; i >= up; i--)
            {
                res[i][left] = ++num;
            }
            left++;
        }
        return res;
    }
};
// left right up down 四个边界

哈希表

242. 有效的字母异位词 - 力扣(LeetCode)

class Solution
{
public:
    bool isAnagram(string s, string t)
    {
        map<char, int> hash;
        for (int i = 0; i < s.size(); i++)
        {
            hash[s[i]]++;
        };

        for (int i = 0; i < t.size(); i++)
        {
            hash[t[i]]--;
        }
        for (auto iter : hash)
        {
            if (iter.second != 0)
            {
                return false;
            }
        }
        return true;
    }
};
// hash['a']++,默认值是 0

349. 两个数组的交集 - 力扣(LeetCode)

class Solution
{
public:
    vector<int> intersection(vector<int> &nums1, vector<int> &nums2)
    {
        vector<int> res;
        std::unordered_set<int> nums1_set(nums1.begin(), nums1.end());
        std::unordered_set<int> nums2_set(nums2.begin(), nums2.end());
        for (auto iter : nums2_set)
        {
            if (nums1_set.find(iter) != nums1_set.end())
            {
                res.emplace_back(iter);
            }
        }
        return res;
    }
};
// 集合哈希

202. 快乐数 - 力扣(LeetCode)

class Solution {
public:
    // 取数值各个位上的单数之和
    int getSum(int n) {
        int sum = 0;
        while (n) {
            sum += (n % 10) * (n % 10);  // 不用再添加()
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> set;
        while(1) {
            int sum = getSum(n);
            if (sum == 1) {
                return true;
            }
            // 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
            if (set.find(sum) != set.end()) {
                return false;
            } else {
                set.insert(sum);
            }
            n = sum;
        }
    }
};

字符串

344. 反转字符串 - 力扣(LeetCode)

class Solution
{
public:
    void reverseString(vector<char> &s)
    {
        int left = 0;
        int right = s.size() - 1;
        while (left < right)
        {
            swap(s[left], s[right]);
            left++;
            right--;
        }
    }
};

541. 反转字符串 II - 力扣(LeetCode)

class Solution
{
public:
    string reverseStr(string s, int k)
    {
        for (int i = 0; i < s.size(); i += 2 * k)
        {

            if (i + k <= s.size())
            {
                std::reverse(s.begin() + i, s.begin() + i + k); // 反转从 i 到 i+k 的部分
            }
            else
            {
                std::reverse(s.begin() + i, s.end());
            }
        }
        return s;
    }
};

// 字符串翻转  std::reverse

151. 反转字符串中的单词 - 力扣(LeetCode)

class Solution
{
public:
    void input_format(string &s)
    {
        int slow = 0;
        for (int fast = 0; fast < s.size(); fast++)
        {
            if (s[fast] != ' ')
            {
                if (slow != 0)
                {
                    s[slow++] = ' '; // 手动添加空格
                }

                while (fast < s.size() && s[fast] != ' ')
                {
                    s[slow++] = s[fast++];  // 注意资源重复赋值,
                };
            }
        }
        s.resize(slow);
    }
    string reverseWords(string s)
    {
        input_format(s);
        std::reverse(s.begin(), s.end());

        int index = 0;
        for (int i = 0; i < s.size(); i++)
        {
            if (s[i] == ' ')
            {
                std::reverse(s.begin() + index, s.begin() + i);
                index = i + 1;
            }
            if (i == s.size()-1)
            {
                std::reverse(s.begin() + index, s.end());
            }
        }
        return s;
    };
};

// 注意std::reverse 区间  [  )

459. 重复的子字符串 - 力扣(LeetCode)

class Solution
{
public:
    bool repeatedSubstringPattern(string s)
    {
        string compare = s + s;
        compare.erase(compare.begin());
        compare.erase(compare.end() - 1);
        if (compare.find(s) != string::npos)
        {
            return true;
        }
        return false;
    }
};

二叉树

144. 二叉树的前序遍历 - 力扣(LeetCode)

class Solution
{
private:
    vector<int> res;

public:
    void pre_look(TreeNode *root)
    {
        if (root == nullptr)
        {
            return;
        }
        res.emplace_back(root->val); // 中
        pre_look(root->left);
        pre_look(root->right);
    }
    vector<int> preorderTraversal(TreeNode *root)
    {
        pre_look(root);
        return res;
    }
};

145. 二叉树的后序遍历 - 力扣(LeetCode)

class Solution
{
private:
    vector<int> res;

public:
    void sub_look(TreeNode *root)
    {
        if (root == nullptr)
        {
            return;
        }
        sub_look(root->left);
        sub_look(root->right);
        res.emplace_back(root->val); // 中
    }
    vector<int> postorderTraversal(TreeNode *root)
    {
        sub_look(root);
        return res;
    }
};

94. 二叉树的中序遍历 - 力扣(LeetCode)

class Solution
{
public:
    vector<int> res;
    void middle_look(TreeNode *root)
    {
        if (root == nullptr)
        {
            return;
        }
        middle_look(root->left);
        res.emplace_back(root->val); // 中
        middle_look(root->right);
    }

public:
    vector<int> inorderTraversal(TreeNode *root)
    {
        middle_look(root);
        return res;
    }
};

102. 二叉树的层序遍历 - 力扣(LeetCode)

class Solution
{
public:
    vector<vector<int>> levelOrder(TreeNode *root)
    {
        vector<vector<int>> res;
        vector<int> res_index;
        queue<TreeNode *> queue;
        if (root != nullptr)
        {
            queue.push(root);
        }
        while (!queue.empty())
        {
            int size = queue.size();
            for (int i = 0; i < size; i++)
            {
                TreeNode *root_index = queue.front();
                res_index.emplace_back(root_index->val);
                queue.pop();
                if (root_index->left)
                {
                    queue.push(root_index->left);
                }
                if (root_index->right)
                {
                    queue.push(root_index->right);
                }
            }
            res.emplace_back(res_index);
            res_index.clear();
        }
        return res;
    }
};

回溯

77. 组合 - 力扣(LeetCode)

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

public:
    void back_track(int n, int k, int index)
    {
        // 子集满足条件
        if (res_index.size() == k)
        {
            res.emplace_back(res_index);
            return;
        }

        for (int i = index; i <= n; i++)
        {
            // 添加当前数
            res_index.emplace_back(i);
            // 访问下一个数
            back_track(n, k, i + 1);
            // 回溯
            res_index.pop_back();
        }
    }

public:
    vector<vector<int>> combine(int n, int k)
    {
        back_track(n, k, 1);
        return res;
    }
};

216. 组合总和 III - 力扣(LeetCode)

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

public:
    void back_track(int n, int k, int index)
    {
        // 子集满足条件
        if (res_index.size() == k && n >= k)
        {
            int sum = 0;
            for (auto iter : res_index)
            {
                sum += iter;
            }
            if (sum == n)
            {
                res.emplace_back(res_index);
            }
            return;
        }

        for (int i = index; i <= 9; i++)
        {
            // 添加当前数
            res_index.emplace_back(i);
            // 访问下一个数
            back_track(n, k, i + 1);
            // 回溯
            res_index.pop_back();
        }
    }

public:
    vector<vector<int>> combinationSum3(int k, int n)
    {
        back_track(n, k, 1);
        return res;
    }
};

动态规划

小米的一道笔试题

(1)小李负责汽车采购业务。公司需要采购一批汽车,保证车可以载X人,承货Y立方米, 小李调研了市场的n种汽年。对第i种汽车价值m_i 元, 有k _i中采购方案。默认的方案可以承载x_i人,承货y_i立方米.第i种选配方案需要金额变化为m_ij元.可以选择特殊的座椅或省支架使得载人和承货能力发生变化,载人变化值为x_ij,载货变化值为y_ij。每辆车能选择一种选配方案,或者选择默认方案。

小李可以同时采购多种汽车的多种选配方案,只希望花费展少的金额满足要求。

输入描述

 第一行包括三个正整数X,Y,N,这三个数取值范围都在[1,200]中.

然后是n组数据: 其中第i组第一行包括四个整教m_i,x_i,y_i,k_i,所有数均小1e5, k可能为0.接下来k_i行每行包括3个整教m_ij,x_ij.y_ij.

样例输入

10 20 2                           

100 2 6 1

20 1 1

80 5 1 1

10 -1 2

样例输出

390

购买第一辆车默认方案3辆,第二辆车的第一种方案1辆。 100*3+90 = 390

#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
using namespace std;
struct car
{
    int cost;
    int passenger;
    int capacity;
};
main()
{
    int X, Y, N;
    cin >> X >> Y >> N;
    vector<car> items; // 存储每个方案的cost, x, y
    for (int i = 0; i < N; ++i)
    {
        int m_i, x_i, y_i, k_i;
        cin >> m_i >> x_i >> y_i >> k_i;
        // 添加默认方案
        items.emplace_back(m_i, x_i, y_i);
        // 处理选配方案
        for (int j = 0; j < k_i; ++j)
        {
            int m_ij, x_ij, y_ij;
            cin >> m_ij >> x_ij >> y_ij;
            int cost = m_i + m_ij;
            int x = x_i + x_ij;
            int y = y_i + y_ij;
            items.emplace_back(cost, x, y);
        }
    }

    // 初始化动态规划数组
    // dp表示在X,Y 情况下,最少的花费。
    vector<vector<long long>> dp(X + 1, vector<long long>(Y + 1, INT_MAX));
    dp[0][0] = 0;

    // 处理每一辆车
    for (const auto &item : items)
    {
        int cost, dx, dy;
        cost = item.cost;
        dx = item.passenger;
        dy = item.capacity;
        for (int a = 0; a <= X; ++a)
        {
            for (int b = 0; b <= Y; ++b)
            {
                if (dp[a][b] == INT_MAX)
                    continue;
                // 计算新的载人和载货量
                int new_a = a + dx;
                // 可能会超额,比如20满足要求,选择出来多了,21,
                new_a = min(new_a, X);
                int new_b = b + dy;
                new_b = min(new_b, Y);
                // 当前的花费少
                if (dp[a][b] + cost < dp[new_a][new_b])
                {
                    // 更新dp数组
                    dp[new_a][new_b] = dp[a][b] + cost;
                }
            }
        }
    }
    cout << dp[X][Y] << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值