第九课 排序

文章目录

  • 第九课 排序
    • 排序算法
    • lc912.排序数组--中等
      • 题目描述
      • 代码展示
    • lc1122.数组的相对排序--简单
      • 题目描述
      • 代码展示
    • lc56.合并区间--中等
      • 题目描述
      • 代码展示
    • lc215.数组中的第k个最大元素--中等
      • 题目描述
      • 代码展示
    • acwing104.货仓选址--简单
      • 题目描述
      • 代码展示
    • lc493.翻转树--困难
      • 题目描述
      • 代码展示
    • lc327.区间个数--困难
      • 题目描述
      • 代码展示

第九课 排序

排序算法

image-20231007161146336

image-20231007161221689

image-20231007161255331

image-20231007161345682

img

image-20231007161402458

image-20231007161428771

image-20231007161441532

image-20231007161454299

image-20231007161510826

快速排序算法动画演示_哔哩哔哩_bilibili

image-20231007161539374

image-20231007161558662

image-20231007161616925

image-20231007161640929

lc912.排序数组–中等

题目描述

给你一个整数数组 nums,请你将该数组升序排列。

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

提示:

  • 1 <= nums.length <= 5 * 104
  • -5 * 104 <= nums[i] <= 5 * 104

代码展示

class Solution {
public:       //堆排序——不会超时vector<int> sortArray(vector<int>& nums) {heapSort(nums);return nums;}private:void heapify(vector<int>& nums, int n, int i) {int largest = i;int left = 2 * i + 1;int right = 2 * i + 2;if (left < n && nums[left] > nums[largest])largest = left;if (right < n && nums[right] > nums[largest])largest = right;if (largest != i) {swap(nums[i], nums[largest]);heapify(nums, n, largest);}}void heapSort(vector<int>& nums) {int n = nums.size();// 建立最大堆for (int i = n / 2 - 1; i >= 0; i--)heapify(nums, n, i);// 逐步提取元素for (int i = n - 1; i > 0; i--) {swap(nums[0], nums[i]);heapify(nums, i, 0);}}
};
class Solution {
public:       //归并排序也可以vector<int> sortArray(vector<int>& nums) {vector<int> tmp(nums.size());mergeSort(nums, tmp, 0, nums.size() - 1);return nums;}private:void merge(vector<int>& nums, vector<int>& tmp, int left, int mid, int right) {int i = left;int j = mid + 1;int k = left;while (i <= mid && j <= right) {if (nums[i] <= nums[j]) {tmp[k++] = nums[i++];} else {tmp[k++] = nums[j++];}}while (i <= mid) {tmp[k++] = nums[i++];}while (j <= right) {tmp[k++] = nums[j++];}for (int l = left; l <= right; l++) {nums[l] = tmp[l];}}void mergeSort(vector<int>& nums, vector<int>& tmp, int left, int right) {if (left < right) {int mid = left + (right - left) / 2;mergeSort(nums, tmp, left, mid);mergeSort(nums, tmp, mid + 1, right);merge(nums, tmp, left, mid, right);}}
};

lc1122.数组的相对排序–简单

题目描述

给你两个数组,arr1arr2arr2 中的元素各不相同,arr2 中的每个元素都出现在 arr1 中。

arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。

示例 1:

输入:arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6]
输出:[2,2,2,1,4,3,3,9,6,7,19]

示例 2:

输入:arr1 = [28,6,22,8,44,17], arr2 = [22,28,8,6]
输出:[22,28,8,6,17,44]

提示:

  • 1 <= arr1.length, arr2.length <= 1000
  • 0 <= arr1[i], arr2[i] <= 1000
  • arr2 中的元素 arr2[i] 各不相同
  • arr2 中的每个元素 arr2[i] 都出现在 arr1

image-20231007162610016

代码展示

你可以使用自定义比较函数来解决这个问题,首先建立一个哈希表,将arr2中的元素与其对应的位置映射起来。然后,使用自定义的比较函数对arr1进行排序,排序规则如下:

  1. 如果a和b都在arr2中,比较它们在arr2中的位置,位置靠前的元素排在前面。
  2. 如果a和b都不在arr2中,直接比较它们的大小。

以下是示例代码:

class Solution {
public:vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {unordered_map<int, int> position;for (int i = 0; i < arr2.size(); i++) {position[arr2[i]] = i;}sort(arr1.begin(), arr1.end(), [&](int a, int b) {if (position.count(a) && position.count(b)) {return position[a] < position[b];} else if (position.count(a)) {return true;} else if (position.count(b)) {return false;} else {return a < b;}});return arr1;}
};

这段代码首先建立了一个哈希表 position,将arr2中的元素与其对应的位置映射起来。然后,使用自定义的比较函数对arr1进行排序,按照上述规则进行比较。这样就能够保证arr1中的元素按照arr2中的相对顺序排列,未在arr2中出现的元素按照升序排在末尾。

如果你想自己实现排序函数,你可以使用计数排序的方法,首先统计arr1中每个元素的出现次数,然后根据arr2的顺序构建排序后的结果。

以下是示例代码:

class Solution {
public:vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {// 统计arr1中每个元素的出现次数vector<int> count(1001, 0);for (int num : arr1) {count[num]++;}vector<int> result;// 根据arr2的顺序构建排序后的结果for (int num : arr2) {while (count[num] > 0) {result.push_back(num);count[num]--;}}// 处理arr2中没有的元素for (int i = 0; i <= 1000; i++) {while (count[i] > 0) {result.push_back(i);count[i]--;}}return result;}
};

这段代码首先使用 count 数组统计了arr1中每个元素的出现次数。然后,根据arr2的顺序构建了排序后的结果,并将结果存储在 result 数组中。最后,处理arr2中没有的元素,将它们按照升序添加到 result 数组中。

这样就能够实现按照arr2的相对顺序对arr1进行排序。

lc56.合并区间–中等

题目描述

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示:

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

image-20231007162657349

代码展示

class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {if (intervals.empty()) {return {};}// 对区间进行双关键字排序(按左端点升序,右端点升序)sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) {return a[0] == b[0] ? a[1] < b[1] : a[0] < b[0];});vector<vector<int>> mergedIntervals;mergedIntervals.push_back(intervals[0]);// 扫描合并for (int i = 1; i < intervals.size(); i++) {vector<int>& currentInterval = intervals[i];vector<int>& previousInterval = mergedIntervals.back();if (currentInterval[0] <= previousInterval[1]) {// 当前区间和前一个区间重叠,合并区间previousInterval[1] = max(previousInterval[1], currentInterval[1]);} else {// 当前区间和前一个区间不重叠,将当前区间添加到结果中mergedIntervals.push_back(currentInterval);}}return mergedIntervals;}
};
class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {/*[1, 5]  [2, 6] [3, 4] [6, 10]  [11 12]1 2 3 4 5 6 7 8 9 10 11 121 1 1 1 11 1 1 1 11 11 1 1 1  11 1+1      -1+1      -1+1-1+1        -1+1 -1count: 0把从1覆盖到5这个区间,看作2个事件:(a) 在1处,有一个事件:开始覆盖(次数+1)(b) 在5处,有一个事件:结束覆盖(次数-1)*/// 产生2n个事件// 时间位置,时间情况(+1/-1)vector<pair<int,int>> events;for (vector<int>& interval : intervals) {// 差分events.push_back(make_pair(interval[0], 1));events.push_back(make_pair(interval[1], -1));}sort(events.begin(), events.end(),[](pair<int,int>& a, pair<int,int>& b) {// 1 在 -1 之前(如果差分是闭区间[1,5]而不是前闭后开[1,6)的话return a.first < b.first || (a.first == b.first && a.second > b.second);});int count = 0;int left;vector<vector<int>> ans;for (pair<int,int>& event : events) {if (count == 0) // 加之前是0,加之后是非0left = event.first;  // 一个段的产生count += event.second;if (count == 0) // 非零变零,一个段的结束ans.push_back({left, event.first});}return ans;}
};

lc215.数组中的第k个最大元素–中等

题目描述

给定整数数组 nums 和整数 k,请返回数组中第 **k** 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

输入: [3,2,1,5,6,4], k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4

提示:

  • 1 <= k <= nums.length <= 105
  • -104 <= nums[i] <= 104

代码展示

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {int left = 0;int right = nums.size() - 1;while (left <= right) {int pivotIndex = partition(nums, left, right);if (pivotIndex == k - 1) {return nums[pivotIndex];} else if (pivotIndex < k - 1) {left = pivotIndex + 1;} else {right = pivotIndex - 1;}}return -1; // 如果输入无效或 k 超出范围,可以返回一个特殊值}int partition(vector<int>& nums, int left, int right) {int pivot = nums[left];int l = left + 1;int r = right;while (l <= r) {if (nums[l] < pivot && nums[r] > pivot) {swap(nums[l++], nums[r--]);}if (nums[l] >= pivot) l++;if (nums[r] <= pivot) r--;}swap(nums[left], nums[r]);return r;}
};

acwing104.货仓选址–简单

题目描述

image-20231007163635776

代码展示

#include <algorithm>using namespace std;const int N = 100005;int n, res;
int a[N];int main()
{scanf("%d", &n);for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);sort(a, a + n);for (int i = 0; i < n; i ++ ) res += abs(a[i] - a[n >> 1]);printf("%d\n", res);return 0;
}

lc493.翻转树–困难

题目描述

给定一个数组 nums ,如果 i < jnums[i] > 2*nums[j] 我们就将 (i, j) 称作一个*重要翻转对*

你需要返回给定数组中的重要翻转对的数量。

示例 1:

输入: [1,3,2,3,1]
输出: 2

示例 2:

输入: [2,4,3,5,1]
输出: 3

注意:

  1. 给定数组的长度不会超过50000
  2. 输入数组中的所有数字都在32位整数的表示范围内。

代码展示

class Solution {
public:int reversePairs(vector<int>& nums) {int n = nums.size();if (n <= 1) {return 0; // 如果数组长度小于等于1,不存在翻转对}vector<int> temp(n); // 用于归并排序的辅助数组return mergeSort(nums, temp, 0, n - 1);}int mergeSort(vector<int>& nums, vector<int>& temp, int left, int right) {if (left >= right) {return 0; // 当子数组长度为1时,不再拆分,返回0}int mid = left + (right - left) / 2;int count = mergeSort(nums, temp, left, mid) + mergeSort(nums, temp, mid + 1, right);int i = left; // 左子数组的起始位置int j = mid + 1; // 右子数组的起始位置int k = left; // 辅助数组的起始位置// 统计翻转对的数量while (i <= mid) {while (j <= right && static_cast<long long>(nums[i]) > 2LL * nums[j]) {j++;}count += (j - (mid + 1)); // 统计右子数组中满足条件的元素数量i++;}// 归并排序合并两个子数组,并保持有序性i = left;j = mid + 1;while (i <= mid && j <= right) {if (nums[i] <= nums[j]) {temp[k++] = nums[i++];} else {temp[k++] = nums[j++];}}while (i <= mid) {temp[k++] = nums[i++];}while (j <= right) {temp[k++] = nums[j++];}for (i = left; i <= right; i++) {nums[i] = temp[i];}return count;}
};

要解决这个问题,可以使用归并排序的思想来统计重要翻转对的数量。具体步骤如下:

  1. 将原始数组拆分成两个子数组。
  2. 分别对两个子数组进行排序。
  3. 遍历其中一个子数组的元素,并查找另一个子数组中满足条件的元素,以统计重要翻转对的数量。
  4. 合并两个子数组时,继续维护它们的有序性。

这段代码首先将原始数组拆分成两个子数组,然后对这两个子数组分别进行归并排序。在归并排序的过程中,统计满足条件的翻转对的数量,并在合并时维护子数组的有序性。最终,返回翻转对的数量。时间复杂度为O(n*log(n))。

lc327.区间个数–困难

题目描述

给你一个整数数组 nums 以及两个整数 lowerupper 。求数组中,值位于范围 [lower, upper] (包含 lowerupper)之内的 区间和的个数

区间和 S(i, j) 表示在 nums 中,位置从 ij 的元素之和,包含 ij (ij)。

示例 1:

输入:nums = [-2,5,-1], lower = -2, upper = 2
输出:3
解释:存在三个区间:[0,0]、[2,2] 和 [0,2] ,对应的区间和分别是:-2 、-1 、2 。

示例 2:

输入:nums = [0], lower = 0, upper = 0
输出:1

提示:

  • 1 <= nums.length <= 105
  • -231 <= nums[i] <= 231 - 1
  • -105 <= lower <= upper <= 105
  • 题目数据保证答案是一个 32 位 的整数

代码展示

class Solution {
public:int countRangeSum(vector<int>& nums, int lower, int upper) {int n = nums.size();vector<long long> prefixSum(n + 1, 0);for (int i = 0; i < n; i++) {prefixSum[i + 1] = prefixSum[i] + nums[i];}return countAndMerge(prefixSum, 0, n, lower, upper);}int countAndMerge(vector<long long>& prefixSum, int left, int right, int lower, int upper) {if (left == right) {return 0; // 递归结束条件}int mid = left + (right - left) / 2;int count = countAndMerge(prefixSum, left, mid, lower, upper) +countAndMerge(prefixSum, mid + 1, right, lower, upper);int i = left;int j = mid + 1;int k = mid + 1;while (i <= mid) {while (j <= right && prefixSum[j] - prefixSum[i] < lower) {j++;}while (k <= right && prefixSum[k] - prefixSum[i] <= upper) {k++;}count += (k - j);i++;}// 归并排序vector<long long> sorted(right - left + 1, 0);int p1 = left;int p2 = mid + 1;int p = 0;while (p1 <= mid || p2 <= right) {if (p1 > mid) {sorted[p++] = prefixSum[p2++];} else if (p2 > right) {sorted[p++] = prefixSum[p1++];} else {if (prefixSum[p1] < prefixSum[p2]) {sorted[p++] = prefixSum[p1++];} else {sorted[p++] = prefixSum[p2++];}}}for (int i = 0; i < sorted.size(); i++) {prefixSum[left + i] = sorted[i];}return count;}
};

要解决这个问题,可以使用归并排序和前缀和的结合方法。具体步骤如下:

  1. 计算前缀和数组 prefixSum,其中 prefixSum[i] 表示 nums 数组中前 i 个元素的和。
  2. 定义一个递归函数 countAndMerge 用于统计区间和个数并归并排序 prefixSum 数组。
  3. countAndMerge 函数中,首先计算中间索引 mid,然后递归计算左半部分和右半部分的区间和个数。
  4. 接下来,合并左半部分和右半部分的区间和,统计符合要求的区间和个数。
  5. 最后,返回区间和个数。

这段代码首先计算前缀和数组 prefixSum,然后使用递归函数 countAndMerge 统计区间和个数并归并排序 prefixSum 数组。在 countAndMerge 函数中,通过归并排序合并左半部分和右半部分的区间和,同时统计满足要求的区间和个数。最终,返回区间和个数。时间复杂度为O(n*log(n))。

image-20231007164248984

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/96614.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript系列从入门到精通系列第十五篇:JavaScript中函数的实参介绍返回值介绍以及函数的立即执行

文章目录 一&#xff1a;函数的参数 1&#xff1a;形参如何定义 2&#xff1a;形参的使用规则 二&#xff1a;函数的返回值 1&#xff1a;函数返回值如何定义 2&#xff1a;函数返回值种类 三&#xff1a;实参的任意性 1&#xff1a;方法可以作为实参 2&#xff1a;将匿…

【Spring Boot】创建一个 Spring Boot 项目

创建一个 Spring Boot 项目 1. 安装插件2. 创建 Spring Boot 项目3. 项目目录介绍和运行注意事项 1. 安装插件 IDEA 中安装 Spring Boot Helper / Spring Assistant / Spring Initializr and Assistant插件才能创建 Spring Boot 项⽬ &#xff08;有时候不用安装&#xff0c;直…

【排序算法】冒泡排序

文章目录 一&#xff1a;排序算法1.1 介绍1.2 分类 二&#xff1a;冒泡排序2.1 基本介绍2.2 图解冒泡排序算法2.3 代码实现 三&#xff1a;算法性能分析3.1 时间复杂度3.2 空间复杂度 一&#xff1a;排序算法 1.1 介绍 排序也称排序算法(Sort Algorithm)&#xff0c;排序是将…

SpringCloud-消息组件

1 简介 了解过RabbitMQ后&#xff0c;可能我们会遇到不同的系统在用不同的队列。比如系统A用的Kafka&#xff0c;系统B用的RabbitMQ&#xff0c;但是没了解过Kafka&#xff0c;因此可以使用Spring Stream&#xff0c;它能够屏蔽地产&#xff0c;像JDBC一样&#xff0c;只关心SQ…

C# 给某个方法设定执行超时时间

C# 给某个方法设定执行超时时间在某些情况下(例如通过网络访问数据)&#xff0c;常常不希望程序卡住而占用太多时间以至于造成界面假死。 在这时、我们可以通过Thread、Thread Invoke&#xff08;UI&#xff09;或者是 delegate.BeginInvoke 来避免界面假死&#xff0c; 但是…

el-table进阶(每条数据分行或合并)

最麻烦的还是css样式&#xff0c;表格样式自己调吧 <!-- ——————————————————————————————————根据数据拓展表格—————————————————————————————————— --> <div style"display: flex"&…

oralce配置访问白名单的方法

目录 配置sqlnet.ora文件 重新加载使配置生效 注意事项 Oracle数据库安全性提升&#xff1a;IP白名单的配置方法 随着互联网的发展&#xff0c;数据库安全问题也越来越严重。Oracle是目前使用较为广泛的一款数据库管理系统&#xff0c;而IP白名单作为提升数据库安全性的有效…

深度学习——权重衰减(weight_decay)

深度学习——权重衰减&#xff08;weight_decay) 文章目录 前言一、权重衰减1.1. 范数与权重衰减1.2. 高维线性回归1.3. 从零开始实现1.3.1.初始化模型参数1.3.2. 定义L₂范数惩罚1.3.3. 定义训练代码实现1.3.4. 不管正则化直接训练1.3.5. 使用权重衰减 1.4. 简洁实现 总结 前言…

vue 项目打包性能分析插件 webpack-bundle-analyzer

webpack-bundle-analyzer 是 webpack 的插件&#xff0c;需要配合 webpack 和 webpack-cli 一起使用。这个插件可以读取输出文件夹&#xff08;通常是 dist&#xff09;中的 stats.json 文件&#xff0c;把该文件可视化展现&#xff0c;生成代码分析报告&#xff0c;可以直观地…

Leetcode901-股票价格跨度

一、前言 本题基于leetcode901股票价格趋势这道题&#xff0c;说一下通过java解决的一些方法。并且解释一下笔者写这道题之前的想法和一些自己遇到的错误。需要注意的是&#xff0c;该题最多调用 next 方法 10^4 次,一般出现该提示说明需要注意时间复杂度。 二、解决思路 ①…

神经网络中的知识蒸馏

多分类交叉熵损失函数&#xff1a;每个样本的标签已经给出&#xff0c;模型给出在三种动物上的预测概率。将全部样本都被正确预测的概率求得为0.70.50.1&#xff0c;也称为似然概率。优化的目标就是希望似然概率最大化。如果样本很多&#xff0c;概率不断连乘&#xff0c;就会造…

关于丢失msvcp71.dll的5个解决办法,msvcp71.dll丢失原因分析

计算机已经成为我们生活和工作中不可或缺的一部分&#xff0c;在使用计算机的过程中&#xff0c;我们经常遇到各种软件或应用程序崩溃的情况。其中&#xff0c;一个常见的错误提示是“MSVCP71.dll丢失”。这个错误通常出现在运行使用Visual C Redistributable for Visual Studi…

数据结构——多重链表的实现

//多重列表的实现 #include<stdio.h> #include<stdlib.h> struct lnode {int row,col,value; }; //没有用到down指针 //没有用到tag和next指针 typedef struct node {int tag;//区分头结点(0)和非零元素结点(1)struct node* right;struct node* down;//共用体与结…

Django基础讲解-路由控制器和视图(Django-02)

一 路由控制器 参考链接&#xff1a; Django源码阅读&#xff1a;路由&#xff08;二&#xff09; - 知乎 Route路由, 是一种映射关系&#xff01;路由是把客户端请求的 url路径与视图进行绑定 映射的一种关系。 这个/timer通过路由控制器最终匹配到myapp.views中的视图函数 …

抄写Linux源码(Day14:从 MBR 到 C main 函数 (3:研究 head.s) )

回忆我们需要做的事情&#xff1a; 为了支持 shell 程序的执行&#xff0c;我们需要提供&#xff1a; 1.缺页中断(不理解为什么要这个东西&#xff0c;只是闪客说需要&#xff0c;后边再说) 2.硬盘驱动、文件系统 (shell程序一开始是存放在磁盘里的&#xff0c;所以需要这两个东…

山西电力市场日前价格预测【2023-10-08】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-10-08&#xff09;山西电力市场全天平均日前电价为258.40元/MWh。其中&#xff0c;最高日前电价为496.19元/MWh&#xff0c;预计出现在18:45。最低日前电价为0.00元/MWh&#xff0c;预计出…

【FreeRTOS】内存管理简单介绍

有没有想过什么移植FreeRTOS时&#xff0c;为什么有多种的内存文件&#xff0c;我们工程只使用Heap_4&#xff0c;其他的有什么用&#xff1f;每个的区别是什么&#xff1f;FreeRTOS是一种流行的实时操作系统&#xff0c;广泛应用于嵌入式系统开发中。在嵌入式系统中&#xff0…

(三)行为模式:8、状态模式(State Pattern)(C++示例)

目录 1、状态模式&#xff08;State Pattern&#xff09;含义 2、状态模式的UML图学习 3、状态模式的应用场景 4、状态模式的优缺点 &#xff08;1&#xff09;优点 &#xff08;2&#xff09;缺点 5、C实现状态模式的实例 1、状态模式&#xff08;State Pattern&#x…

光伏发电预测(LSTM、CNN_LSTM和XGBoost回归模型,Python代码)

运行效果&#xff1a;光伏发电预测&#xff08;LSTM、CNN_LSTM和XGBoost回归模型&#xff0c;Python代码&#xff09;_哔哩哔哩_bilibili 运行环境库的版本 光伏太阳能电池通过互连形成光伏模块&#xff0c;以捕捉太阳光并将太阳能转化为电能。因此&#xff0c;当光伏模块暴露…

深入探究 C++ 编程中的资源泄漏问题

目录 1、GDI对象泄漏 1.1、何为GDI资源泄漏&#xff1f; 1.2、使用GDIView工具排查GDI对象泄漏 1.3、有时可能需要结合其他方法去排查 1.4、如何保证没有GDI对象泄漏&#xff1f; 2、进程句柄泄漏 2.1、何为进程句柄泄漏&#xff1f; 2.2、创建线程时的线程句柄泄漏 …